C# 为集成测试播种WebApplicationFactory不会';t保存并给出一个404

C# 为集成测试播种WebApplicationFactory不会';t保存并给出一个404,c#,asp.net,testing,.net-core,integration-testing,C#,Asp.net,Testing,.net Core,Integration Testing,因此,我试图在dbcontext中使用预种子数据创建一个集成测试,但由于某些原因,它没有将我的条目保存到数据库中,并在我得到响应后给我一个404 not found。如果需要的话,很乐意扩展或澄清任何内容 干杯 [Fact] public async Task GetPet_ReturnsResourceWithAccurateFields() { var fakePet = new FakePet { }.Generate(); fakePet.PetId = 1;

因此,我试图在dbcontext中使用预种子数据创建一个集成测试,但由于某些原因,它没有将我的条目保存到数据库中,并在我得到响应后给我一个404 not found。如果需要的话,很乐意扩展或澄清任何内容

干杯

[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);
}
[事实]
公共异步任务GetPet_返回带有AccurateFields()的资源
{
var fakePet=new fakePet{}.Generate();
fakePet.PetId=1;
var appFactory=new WebApplicationFactory()
.WithWebHostBuilder(builder=>
{
建设者
.ConfigureServices(服务=>
{
删除(新的ServiceDescriptor(typeof(MyDbContext)),
typeof(MyDbContext));
services.AddDbContext(选项=>
{
选项。使用MemoryDatabase(“TestDb”);
});
var serviceProvider=服务
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
使用(var scope=serviceProvider.CreateScope())
{
var context=scope.ServiceProvider.GetRequiredService();
context.Database.recreated();
context.Pets.AddRange(fakePet);
SaveChanges();
}
});
});
var testingClient=appFactory.CreateClient();
var result=await testingClient.GetAsync($“/v1/Pets/{fakePet.PetId}”);
var responseContent=wait result.Content.ReadAsStringAsync();
var response=JsonConvert.DeserializeObject(responseContent);
//断言
response.Name.Should().Be(fakePet.Name);
response.Age.Should().Be(fakePet.Age);
}
可能是因为您创建的(中间)服务提供程序获得了内存中数据库的独立实例

创建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 ...

var-appFactory=new-WebApplicationFactory()
.WithWebHostBuilder(builder=>
{
等
});
使用(var scope=appFactory.Services.CreateScope())
{
var context=scope.ServiceProvider.GetRequiredService();
context.Database.recreated();
context.Pets.AddRange(fakePet);
SaveChanges();
}
var testingClient=appFactory.CreateClient();
... 等

welcome-请提供一个例子,我试图通过提供完整的测试代码来保持它的完整性,但您还需要我添加什么?如果不共享整个项目,这是不完全可复制的。日志和控制器会很好。感谢您的回复。这是有道理的,但我没有看到WebApplicationFactory中使用的服务定义,也没有看到像我在OP中看到的那样在webhostbuilder内部钻取的方法。有什么建议吗?我自己也会继续挖掘。恐怕它只适用于.NET Core 3.x,但它应该只是到appFactory.Server.Host.Services的快捷方式