asp.net - Autofac OWIN TestServer 和 HttpContext

标签 asp.net asp.net-mvc-5 integration-testing autofac asp.net-web-api2

我正在尝试使用我的 IIS 托管 WebAPI 2.2 应用程序设置集成测试。我使用 Autofac 进行 DI,并且使用新的 ASP.net Identity 堆栈(该堆栈使用 OWIN)。我遇到了 Autofac 的问题,其中 HttpContext 类始终为 null。这是我设置基本集成测试类的方法-

 [TestClass]
public class TestBase
{
    private SimpleLifetimeScopeProvider _scopeProvider;
    private IDependencyResolver _originalResolver;
    private HttpConfiguration _configuration;
    public TestServer Server { get; private set; }

    [TestInitialize]
    public void Setup()
    {
        Server = TestServer.Create(app =>
        {
            //config webpai
            _configuration = new HttpConfiguration();
            WebApiConfig.Register(_configuration);

            // Build the container.
            var container = App_Start.IocConfig.RegisterDependencies(_configuration);
            _scopeProvider = new SimpleLifetimeScopeProvider(container);

            //set the mvc dep resolver
            var mvcResolver = new AutofacDependencyResolver(container, _scopeProvider);
            _originalResolver = DependencyResolver.Current;
            DependencyResolver.SetResolver(mvcResolver);

            //set the webapi dep resolvers
            _configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            app.UseAutofacMiddleware(container);
            app.UseAutofacWebApi(_configuration);
            app.UseAutofacMvc();
        });
    }

    [TestCleanup]
    public void Cleanup()
    {
        // Clean up the fake 'request' scope.
        _configuration.Dispose();
        DependencyResolver.SetResolver(_originalResolver);
        _scopeProvider.EndLifetimeScope();
        Server.Dispose();
    }
}

当一个简单的测试开始时,我收到一个 ArgumentNullException“值不能为空”httpContext。如果我追踪 autofac 代码,我认为它来自这个扩展方法 -

 public static class AutofacMvcAppBuilderExtensions
    {
        internal static Func<HttpContextBase> CurrentHttpContext = () => new HttpContextWrapper(HttpContext.Current);

        /// <summary>
        /// Extends the Autofac lifetime scope added from the OWIN pipeline through to the MVC request lifetime scope.
        /// </summary>
        /// <param name="app">The application builder.</param>
        /// <returns>The application builder.</returns>
        [SecuritySafeCritical]
        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
        public static IAppBuilder UseAutofacMvc(this IAppBuilder app)
        {
            return app.Use(async (context, next) =>
            {
                var lifetimeScope = context.GetAutofacLifetimeScope();
                var httpContext = CurrentHttpContext();

                if (lifetimeScope != null && httpContext != null)
                    httpContext.Items[typeof(ILifetimeScope)] = lifetimeScope;

                await next();
            });
        }
    }

位于 Core/Source/Autofac.Integration.Mvc.Owin/AutofacMvcAppBuilderExtensions.cs文件。我的设置是否存在问题,或者在使用 IIS 主机和 OWIN 中间件的 WebApi 应用程序的集成测试中使用 Autofac 的正确方法是否存在问题?

最佳答案

看来您已经问过这个问题 as an issue over on the Autofac project 。我将在这里复制/粘贴答案(尽管将来最好选择其中之一,而不是两者都选择)。

仅使用 OWIN 的应用程序的部分优点是您不再需要 HttpContext。与此无关;相反,它都是 HttpContextBase 以及与旧版 IIS 分离的东西。就像在 Web API 中一样,当前上下文始终随 HttpRequestMessage 一起提供 - 没有全局静态 HttpContext.Current,因为那是遗留的东西。

因此,当您使用 OWIN 测试主机运行单元测试时,您可以预期不会有 HttpContext.Current。它与这一切脱钩。

MVC can't run as OWIN-only because the libraries are tightly coupled to the legacy IIS/ASP.NET stack.尝试使用仅限 OWIN 的测试服务器来测试 MVC 内容会给您带来这样的麻烦。随着新的 ASP.NET 5.0 与新的 Visual Studio 一起发布,这种情况将会改变。

如果您需要以集成方式测试 MVC,目前还没有办法使用 OWIN 来实现这一点。您必须启动 IIS Express。

最后,我确实发现您缺少 OWIN 的 Web API 中间件(实际的 Microsoft Web API 中间件)。这可能会给您带来其他问题。

app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(_configuration);
app.UseAutofacMvc();
// You're missing this:
app.UseWebApi(config);

关于asp.net - Autofac OWIN TestServer 和 HttpContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26512570/

相关文章:

asp.net - 使用 Sitecore DMS 是否需要页面编辑器和 "cloning"?

c# - 回发后保留以编程方式创建的 html 控件

javascript - 为什么我的 jquery 脚本在从 MasterPage 继承的网络表单中不起作用?

ruby-on-rails - 我的 Rails 应用程序外部端点的集成测试的良好做法?

ruby-on-rails-3 - 在 Rspec 集成测试中为对象设置 session

c# - 在 asp.net 中创建日期时间选择器

asp.net-mvc - 没有类型为 'IEnumerable<SelectListItem>' 的 ViewData 项具有 key 'SubGoods'

c# - 枚举到 MVC 5 中的下拉列表

asp.net - 如何让 MVCSiteMap 将所有自定义生成的页面包含在 sitemap.xml 中

java - 有没有办法在使用 Spring 或 Spring Boot 的 JUnit 测试中使用 Autowired 构造函数?