我遇到了同样的问题,但我设法解决了它,至少是为了满足我自己的基本需求。如果您仍然需要解决方案,这就是我所做的。
注意:如果有人知道更好的方法或发现以下任何缺陷,我将非常高兴听到。
我有一个IntegrationTestWebApplicationFactory,我用它来为我的集成测试做通常的配置。正如 Pavel 已经指出的那样,您可以在测试开始之前以编程方式运行迁移。为此,我的IntegrationTestWebApplicationFactory实现了XUnit的IAsyncLifetime接口,我正在使用它进行测试。这个接口要求你实现InitializeAsync和DisposeAsync方法。在 InitializeAsync 中,我运行 await dbContext.Database.MigrateAsync(); 命令。
这是我的IntegrationTestWebApplicationFactory 类的完整代码:
public class IntegrationTestWebApplicationFactory : WebApplicationFactory<Program>, IAsyncLifetime
{
private readonly TestcontainerDatabase _container;
public IntegrationTestFactory()
{
_container = new TestcontainersBuilder<MsSqlTestcontainer>()
.WithDatabase(new MsSqlTestcontainerConfiguration
{
Username = "sa",
Database = "WeatherApp",
Password = "2@LaiNw)PDvs^t>L!Ybt]6H^%h3U>M",
})
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
.WithCleanUp(true)
.Build();
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestServices(services =>
{
services.AddDbContext<DemoDbContext>(options => { options.UseSqlServer(_container.ConnectionString); });
});
}
public async Task InitializeAsync()
{
await _container.StartAsync();
using var scope = Services.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<DemoDbContext>();
await dbContext.Database.MigrateAsync();
}
public new async Task DisposeAsync() => await _container.DisposeAsync();
}
这就是我在集成测试中使用它的方式:
[Theory]
[InlineAutoData]
public async Task GettingWeatherForecastReturnsOkay(WeatherForecast expectedForecast)
{
var client = _integrationTestFactory.CreateClient();
// insert into db what you want to assert
await client.PostAsJsonAsync("WeatherForecast", expectedForecast);
// read from db
var forecasts = await client.GetFromJsonAsync<List<WeatherForecast>>("WeatherForecast");
// do asserts or whatever..
forecasts.Should().NotBeEmpty();
forecasts.Should().ContainEquivalentOf(expectedForecast);
}