Mocking the database in tests is a lie. In-memory databases (like EF Core InMemory) behave differently than SQL Server. **Testcontainers** allows you to spin up real, throwaway Docker containers for your integration tests.
Setup in xUnit
public class IntegrationTest : IAsyncLifetime
{
private readonly MsSqlContainer _dbContainer = new MsSqlBuilder()
.WithPassword("StrongP@ssw0rd!")
.Build();
public async Task InitializeAsync()
{
await _dbContainer.StartAsync();
// Run migrations...
}
public async Task DisposeAsync()
{
await _dbContainer.StopAsync();
}
}
Writing the Test
[Fact]
public async Task CreateOrder_ShouldPersist_ToRealSql()
{
var options = new DbContextOptionsBuilder()
.UseSqlServer(_dbContainer.GetConnectionString())
.Options;
using var context = new MyDbContext(options);
context.Orders.Add(new Order { Total = 100 });
await context.SaveChangesAsync();
var saved = await context.Orders.FirstAsync();
Assert.Equal(100, saved.Total);
}
Key Takeaways
- Test against the exact version of the database you use in production.
- Works for Redis, RabbitMQ, Kafka, etc.
- Requires Docker Desktop to be running.
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.