替换应用程序中类注入的HttpContext

问题描述 投票:0回答:3

我正在使用 xunit、respawn 和 webapplicationfactory 为 mediatr 处理程序设置一些集成测试....

最终由正在测试的 mediatr 处理程序调用的类之一..依赖于 IHttpContextAccessor,如下所示

我觉得我已经设置了我想要正确注入的“替换”单例,如下所示:

但是当集成测试运行时.. httpContextAccessor 不为 null,但 HttpContext 始终为 null。

我已经尝试了大约 600 万件事:(非常悲伤。

如何让 IHttpContextAccessor 正确解析我在 ConfigureServices 中设置的内容?

asp.net-core dependency-injection asp.net-core-3.1 httpcontext mediatr
3个回答
1
投票

我需要自己实现 IHttpContextAccessor

然后在WebApplicationFactory的ConfigureTestServices中利用ConfigureWebHost


0
投票

当集成测试运行时.. httpContextAccessor 不为 null,但 HttpContext 始终为 null。如何让 IHttpContextAccessor 正确解析为我的内容 在ConfigureServices中设置?

不,我们不能,HttpContext 仅在请求范围内可用,因为在构造 Startup 之前调用了ConfigureServices,因此如果我们尝试注入,它将通过异常,即使我们在该场景中声明全局变量,它也将始终为 null 。应用程序启动仅发生一次,并且早在收到任何请求之前。

让我们尝试在 IConfiguration 中访问它,如下所示:

public Startup(IConfiguration configuration,IHttpContextAccessor httpContextAccessor)
        {
            Configuration = configuration;

            HttpContextAccessor = httpContextAccessor;


        }

        public IConfiguration Configuration { get; }
        public IHttpContextAccessor HttpContextAccessor { get; }

输出:

如您所见,它不允许我们这样做。

即使我们尝试将其注入配置本身,它最终也会出现以下异常:

因此,ConfigureServices 在任何 httprequest 到达应用程序之前运行一次。如果我们强行尝试在请求生命周期之外调用它,它总是会以 NullReferenceException 结束。您可以在官方文档中获得更多详细信息。

除此之外,我们还可以在配置中注入服务引用,如下所示:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

0
投票

接受的答案也对我有用,但我的问题是我不小心添加了:

services.AddHttpContextAccessor();
ConfigureTestServices
方法内。所以最终的设置应该是这样的(因为接受的答案有图像而不是代码):

MockHttpContextAccessor.cs

public class MockHttpContextAccessor : IHttpContextAccessor
{
    HttpContext? IHttpContextAccessor.HttpContext { get; set; } = new DefaultHttpContext
    {
        User = new GenericPrincipal(
            new GenericIdentity("test-user"), new[] { "sample-role" })
    };
}

WebApplicationFactory 类中的ConfigureWebHost 方法:

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
    builder.ConfigureTestServices(services =>
    {
        services.AddSingleton<IHttpContextAccessor, MockHttpContextAccessor>();
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.