I had the same problem and I managed to solve it, at least for my own basic needs. In case you still need a solution, here is what I did.
Note: If anyone knows a better approach or spots any flaws below, I would be very happy to hear about it.
I have a IntegrationTestWebApplicationFactory which I use to do the usual configuration for my integration tests. As Pavel already pointed out, you can run the migrations programmatically before the tests start. For this, my IntegrationTestWebApplicationFactoryimplements the IAsyncLifetime interface of XUnit, which I am using for testing. This interface requires you to implement InitializeAsync and DisposeAsync methods. Inside of InitializeAsync I run the await dbContext.Database.MigrateAsync(); command.
Here is the full code of my IntegrationTestWebApplicationFactory class:
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();
}
And this is how I used it in my integration tests:
[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);
}