【问题标题】:Seeding WebApplicationFactory For Integration Tests Doesn't Save and Gives a 404为集成测试播种 WebApplicationFactory 不保存并给出 404
【发布时间】:2020-02-06 20:02:14
【问题描述】:

所以我正在尝试使用我的 dbcontext 中的预置数据创建一个集成测试,但由于某种原因,它没有将我的条目保存到数据库中,并且在我得到回复后给我一个 404 未找到。如果需要,很乐意扩展或澄清任何内容。

干杯

[Fact]
public async Task GetPet_ReturnsResourceWithAccurateFields()
{
    var fakePet = new FakePet { }.Generate();
    fakePet.PetId = 1;

    var appFactory = new WebApplicationFactory<StartupAutomatedTesting>()
        .WithWebHostBuilder(builder =>
        {
            builder
                .ConfigureServices(services =>
                {
                    services.Remove(new ServiceDescriptor(typeof(MyDbContext),
                        typeof(MyDbContext)));
                    services.AddDbContext<MyDbContext>(options =>
                    {
                        options.UseInMemoryDatabase("TestDb");
                    });

                    var serviceProvider = services
                        .AddEntityFrameworkInMemoryDatabase()
                        .BuildServiceProvider();

                    using (var scope = serviceProvider.CreateScope())
                    {
                        var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
                        context.Database.EnsureCreated();

                        context.Pets.AddRange(fakePet);
                        context.SaveChanges();
                    }
                });
        });

    var testingClient = appFactory.CreateClient();


    var result = await testingClient.GetAsync($"/v1/Pets/{fakePet.PetId}");
    var responseContent = await result.Content.ReadAsStringAsync();
    var response = JsonConvert.DeserializeObject<PetDto>(responseContent);

    // Assert
    response.Name.Should().Be(fakePet.Name);
    response.Age.Should().Be(fakePet.Age);
}

【问题讨论】:

  • 欢迎 - 请提供minimal reproducible example
  • 我试图通过提供完整的测试代码来保持它的最小化但完整,但是您还需要我添加什么?如果不共享整个项目,这实际上是无法完全重现的。
  • 日志和控制器会很棒。

标签: c# asp.net testing .net-core integration-testing


【解决方案1】:

可能是因为您创建的(中间)服务提供者获得了自己的内存数据库单例实例。

在创建 appFactory 后移动种子部分,并从 appFactory 解析来自服务提供者的 dbcontext:

var appFactory = new WebApplicationFactory<StartupAutomatedTesting>()
   .WithWebHostBuilder(builder =>
   {
       ... etc ...
   });

using (var scope = appFactory.Services.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
    context.Database.EnsureCreated();

    context.Pets.AddRange(fakePet);
    context.SaveChanges();
}

var testingClient = appFactory.CreateClient();

... etc ...

【讨论】:

  • 感谢您的回复。这是有道理的,但我没有看到要在 WebApplicationFactory 中使用的服务定义,也没有像在 OP 中那样在 webhostbuilder 内部进行深入研究的方法。有什么建议?我也会继续挖掘自己。
  • 恐怕它只适用于.NET Core 3.x docs.microsoft.com/en-us/dotnet/api/… 但它应该只是appFactory.Server.Host.Services的快捷方式
猜你喜欢
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 2019-03-19
  • 2022-06-16
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多