Inheritance: System.Web.Mvc.ControllerActionInvoker, ITestActionInvoker
        private TestControllerActionInvoker CreateInvoker(
            IFilter[] filters,
            bool actionThrows = false,
            ITempDataDictionary tempData = null,
            int maxAllowedErrorsInModelState = 200)
        {
            var actionDescriptor = new ControllerActionDescriptor()
            {
                FilterDescriptors = new List<FilterDescriptor>(),
                Parameters = new List<ParameterDescriptor>(),
            };

            if (actionThrows)
            {
                actionDescriptor.MethodInfo = typeof(ControllerActionInvokerTest).GetMethod("ThrowingActionMethod");
            }
            else
            {
                actionDescriptor.MethodInfo = typeof(ControllerActionInvokerTest).GetMethod("ActionMethod");
            }

            tempData = tempData ?? new Mock<ITempDataDictionary>().Object;
            var httpContext = new Mock<HttpContext>(MockBehavior.Loose);
            var httpRequest = new DefaultHttpContext().Request;
            var httpResponse = new DefaultHttpContext().Response;

            httpContext.SetupGet(c => c.Request).Returns(httpRequest);
            httpContext.SetupGet(c => c.Response).Returns(httpResponse);
            httpContext.Setup(o => o.RequestServices.GetService(typeof(ITempDataDictionary)))
                       .Returns(tempData);
            httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger<ObjectResult>)))
                       .Returns(new Mock<ILogger<ObjectResult>>().Object);

            httpResponse.Body = new MemoryStream();

            var formatter = new Mock<IOutputFormatter>();
            formatter
                .Setup(f => f.CanWriteResult(It.IsAny<OutputFormatterContext>(), It.IsAny<MediaTypeHeaderValue>()))
                .Returns(true);

            formatter
                .Setup(f => f.WriteAsync(It.IsAny<OutputFormatterContext>()))
                .Returns<OutputFormatterContext>(async c =>
                {
                    await c.HttpContext.Response.WriteAsync(c.Object.ToString());
                });

            var options = new MvcOptions();
            options.OutputFormatters.Add(formatter.Object);

            var optionsAccessor = new Mock<IOptions<MvcOptions>>();
            optionsAccessor
                .SetupGet(o => o.Options)
                .Returns(options);

            httpContext
                .Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
                .Returns(optionsAccessor.Object);

            var actionContext = new ActionContext(
                httpContext: httpContext.Object,
                routeData: new RouteData(),
                actionDescriptor: actionDescriptor);

            var filterProvider = new Mock<IFilterProvider>(MockBehavior.Strict);
            filterProvider
                .Setup(fp => fp.OnProvidersExecuting(It.IsAny<FilterProviderContext>()))
                .Callback<FilterProviderContext>(context =>
                    {
                        foreach (var filter in filters.Select(f => new FilterItem(null, f)))
                        {
                            context.Results.Add(filter);
                        }
                    });

            filterProvider.Setup(fp => fp.OnProvidersExecuted(It.IsAny<FilterProviderContext>()))
                          .Verifiable();

            filterProvider.SetupGet(fp => fp.Order)
                          .Returns(DefaultOrder.DefaultFrameworkSortOrder);

            var invoker = new TestControllerActionInvoker(
                actionContext,
                new[] { filterProvider.Object },
                new MockControllerFactory(this),
                actionDescriptor,
                new IInputFormatter[0],
                new IOutputFormatter[0],
                Mock.Of<IControllerActionArgumentBinder>(),
                new IModelBinder[0],
                new IModelValidatorProvider[0],
                new IValueProviderFactory[0],
                new MockScopedInstance<ActionBindingContext>(),
                tempData,
                new NullLoggerFactory(),
                maxAllowedErrorsInModelState);

            return invoker;
        }
        private TestControllerActionInvoker CreateInvoker(
            IFilterMetadata[] filters,
            bool actionThrows = false,
            int maxAllowedErrorsInModelState = 200)
        {
            var actionDescriptor = new ControllerActionDescriptor()
            {
                FilterDescriptors = new List<FilterDescriptor>(),
                Parameters = new List<ParameterDescriptor>(),
            };

            if (actionThrows)
            {
                actionDescriptor.MethodInfo = typeof(ControllerActionInvokerTest).GetMethod("ThrowingActionMethod");
            }
            else
            {
                actionDescriptor.MethodInfo = typeof(ControllerActionInvokerTest).GetMethod("ActionMethod");
            }

            var httpContext = new Mock<HttpContext>(MockBehavior.Loose);

            var http = GetHttpContext();

            var httpRequest = http.Request;
            var httpResponse = http.Response;

            httpContext.SetupGet(c => c.Request).Returns(httpRequest);
            httpContext.SetupGet(c => c.Response).Returns(httpResponse);
            httpContext
                .Setup(o => o.RequestServices.GetService(typeof(ILoggerFactory)))
                .Returns(NullLoggerFactory.Instance);

            httpResponse.Body = new MemoryStream();

            var formatter = new Mock<IOutputFormatter>();
            formatter
                .Setup(f => f.CanWriteResult(It.IsAny<OutputFormatterCanWriteContext>()))
                .Returns(true);

            formatter
                .Setup(f => f.WriteAsync(It.IsAny<OutputFormatterWriteContext>()))
                .Returns<OutputFormatterWriteContext>(async c =>
                {
                    await c.HttpContext.Response.WriteAsync(c.Object.ToString());
                });

            var options = new MvcOptions();
            options.OutputFormatters.Add(formatter.Object);

            var optionsAccessor = new Mock<IOptions<MvcOptions>>();
            optionsAccessor
                .SetupGet(o => o.Value)
                .Returns(options);

            httpContext
                .Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
                .Returns(optionsAccessor.Object);

            var actionContext = new ActionContext(
                httpContext: httpContext.Object,
                routeData: new RouteData(),
                actionDescriptor: actionDescriptor);

            var filterProvider = new Mock<IFilterProvider>(MockBehavior.Strict);
            filterProvider
                .Setup(fp => fp.OnProvidersExecuting(It.IsAny<FilterProviderContext>()))
                .Callback<FilterProviderContext>(context =>
                    {
                        foreach (var filterMetadata in filters)
                        {
                            var filter = new FilterItem(
                                new FilterDescriptor(filterMetadata, FilterScope.Action),
                                filterMetadata);
                            context.Results.Add(filter);
                        }
                    });

            filterProvider
                .Setup(fp => fp.OnProvidersExecuted(It.IsAny<FilterProviderContext>()))
                .Verifiable();

            var actionArgumentsBinder = new Mock<IControllerActionArgumentBinder>();
            actionArgumentsBinder.Setup(
                    b => b.BindActionArgumentsAsync(It.IsAny<ControllerContext>(), It.IsAny<object>()))
                .Returns(Task.FromResult<IDictionary<string, object>>(new Dictionary<string, object>()));

            filterProvider
                .SetupGet(fp => fp.Order)
                .Returns(-1000);

            var invoker = new TestControllerActionInvoker(
                actionContext,
                new[] { filterProvider.Object },
                new MockControllerFactory(this),
                actionDescriptor,
                new IInputFormatter[0],
                actionArgumentsBinder.Object,
                new IModelBinder[0],
                new IModelValidatorProvider[0],
                new IValueProviderFactory[0],
                new NullLoggerFactory().CreateLogger<ControllerActionInvoker>(),
                new DiagnosticListener("Microsoft.AspNet"),
                maxAllowedErrorsInModelState);
            return invoker;
        }
        private TestControllerActionInvoker CreateInvoker(
            IFilter[] filters,
            bool actionThrows = false,
            ITempDataDictionary tempData = null)
        {
            var actionDescriptor = new ControllerActionDescriptor()
            {
                FilterDescriptors = new List<FilterDescriptor>(),
                Parameters = new List<ParameterDescriptor>(),
            };

            if (actionThrows)
            {
                actionDescriptor.MethodInfo = typeof(ControllerActionInvokerTest).GetMethod("ThrowingActionMethod");
            }
            else
            {
                actionDescriptor.MethodInfo = typeof(ControllerActionInvokerTest).GetMethod("ActionMethod");
            }

            tempData = tempData ?? new Mock<ITempDataDictionary>().Object;
            var httpContext = new Mock<HttpContext>(MockBehavior.Loose);
            var httpRequest = new DefaultHttpContext().Request;
            var httpResponse = new DefaultHttpContext().Response;
            var mockFormattersProvider = new Mock<IOutputFormattersProvider>();
            mockFormattersProvider.SetupGet(o => o.OutputFormatters)
                                  .Returns(
                                        new List<IOutputFormatter>()
                                        {
                                            new JsonOutputFormatter()
                                        });
            httpContext.SetupGet(c => c.Request).Returns(httpRequest);
            httpContext.SetupGet(c => c.Response).Returns(httpResponse);
            httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
                       .Returns(mockFormattersProvider.Object);
            httpContext.Setup(o => o.RequestServices.GetService(typeof(ITempDataDictionary)))
                       .Returns(tempData);
            httpResponse.Body = new MemoryStream();

            var options = new Mock<IOptions<MvcOptions>>();
            options.SetupGet(o => o.Options)
                       .Returns(new MvcOptions());
            httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
                       .Returns(options.Object);

            var actionContext = new ActionContext(
                httpContext: httpContext.Object,
                routeData: new RouteData(),
                actionDescriptor: actionDescriptor);

            var filterProvider = new Mock<IFilterProvider>(MockBehavior.Strict);
            filterProvider
                .Setup(fp => fp.OnProvidersExecuting(It.IsAny<FilterProviderContext>()))
                .Callback<FilterProviderContext>(context =>
                    {
                        foreach (var filter in filters.Select(f => new FilterItem(null, f)))
                        {
                            context.Results.Add(filter);
                        }
                    });

            filterProvider.Setup(fp => fp.OnProvidersExecuted(It.IsAny<FilterProviderContext>()))
                          .Verifiable();

            filterProvider.SetupGet(fp => fp.Order)
                          .Returns(DefaultOrder.DefaultFrameworkSortOrder);


            var inputFormattersProvider = new Mock<IInputFormattersProvider>();
            inputFormattersProvider.SetupGet(o => o.InputFormatters)
                                            .Returns(new List<IInputFormatter>());
            var excludeFilterProvider = new Mock<IValidationExcludeFiltersProvider>();
            excludeFilterProvider.SetupGet(o => o.ExcludeFilters)
                                 .Returns(new List<IExcludeTypeValidationFilter>());
            var invoker = new TestControllerActionInvoker(
                actionContext,
                new[] { filterProvider.Object },
                new MockControllerFactory(this),
                actionDescriptor,
                inputFormattersProvider.Object,
                Mock.Of<IControllerActionArgumentBinder>(),
                new MockModelBinderProvider(),
                new MockModelValidatorProviderProvider(),
                new MockValueProviderFactoryProvider(),
                new MockScopedInstance<ActionBindingContext>(),
                tempData);

            return invoker;
        }