为了账号安全,请及时绑定邮箱和手机立即绑定

ASP.NET Core 2.2 集成测试 DbContext 服务未注册

ASP.NET Core 2.2 集成测试 DbContext 服务未注册

C#
函数式编程 2022-12-24 14:57:24
设置视窗 10Visual Studio 专业版 2017 v15.9.9ASP.NET 核心 2.2英孚核心 2.2小巧玲珑xUnit 2.4.1描述我正在使用WebApplicationFactory包中的Microsoft.AspNetCore.Mvc.Testing来设置我的集成测试。我一直在关注官方文档来自定义虚拟主机配置。SUT 使用 Dapper 从数据库中查询,因此我没有使用 EF Core 附带的内存提供程序来进行此特定集成测试。我设置的代码WebApplictionFactory如下:public class CustomWebApplicationFactory<TStartup>    : WebApplicationFactory<TStartup> where TStartup : class{    protected override void ConfigureWebHost(IWebHostBuilder builder)    {        builder            .UseStartup<TStartup>()            .ConfigureServices(services =>        {            var sp = services.BuildServiceProvider();            // Create a scope to obtain a reference to the database context            using (var scope = sp.CreateScope())                {                var scopedServices = scope.ServiceProvider;                var dbContext = scopedServices.GetRequiredService<MyDbContext>(); // <-- service not found                dbContext.Database.EnsureCreated();                new MyDbContextSeed()                    .SeedAsync(dbContext)                    .Wait();            }        });    }}问题MyDbContext找不到该服务,我明白为什么(我认为)- 因为ServiceProvider我的Startup.cs班级尚未构建。但问题是如何从我的 Startup 类访问服务?对于上下文,集成测试如下所示:public class MyAPITests    : IClassFixture<CustomWebApplicationFactory<Startup>>{    private readonly HttpClient _client;    private readonly CustomWebApplicationFactory<Startup> _factory;    public MyAPITests(CustomWebApplicationFactory<Startup> factory)    {        _factory = factory;        _client = factory.CreateClient();    }    [Fact]    public async Task Get_ItemAsync_WhenIdNotFound_ReturnsNotFoundStatusCode()    {        // Arrange        var request = new HttpRequestMessage(HttpMethod.Get, "api/v1/item/0");        // Act        var response = await _client.SendAsync(request);        // Assert        Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);    }}
查看完整描述

1 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

首先,ConfigureServices可以代替UseStartup,不能一起使用。其次,您不应该创建范围并在此期间进行迁移ConfigureServices,而是在构建 Web 主机之后,请参见此处:


Configure在较早的教程中,您可能会在 Startup.cs的方法中看到类似的代码。我们建议您仅使用 Configure 方法来设置请求管道。应用程序启动代码属于该 Main方法。


这样做的唯一方法不是在工厂中,而是在工厂建造之后:


public class MyAPITests

    : IClassFixture<CustomWebApplicationFactory<Startup>>

{

    private readonly HttpClient _client;

    private readonly CustomWebApplicationFactory<Startup> _factory;


    public MyAPITests(CustomWebApplicationFactory<Startup> factory)

    {

        _factory = factory;

        _client = factory.CreateClient();


        var host = factory.Server.Host;

        using (var scope = host.Services.CreateScope())

        {

            var scopedServices = scope.ServiceProvider;

            var dbContext = scopedServices.GetRequiredService<MyDbContext>();


            dbContext.Database.EnsureCreated();


            new MyDbContextSeed()

                .SeedAsync(dbContext)

                .Wait();

        }

    }


    //...

}


查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 82 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信