Add EF Core Code First sample with per-test schema isolation#4840
Add EF Core Code First sample with per-test schema isolation#4840
Conversation
Code ReviewResource Leak IssueFile: Issue: The protected TodoDbContext CreateDbContext()
{
var scope = Factory.Services.CreateScope(); // ⚠️ scope is never disposed
var dbContext = scope.ServiceProvider.GetRequiredService<TodoDbContext>();
dbContext.SchemaName = SchemaName;
return dbContext; // only DbContext returned; scope leaks
}Problem: Callers use Impact:
Suggested Fix: Return both the scope and context so callers can dispose both: protected (TodoDbContext DbContext, IServiceScope Scope) CreateDbContext()
{
var scope = Factory.Services.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<TodoDbContext>();
dbContext.SchemaName = SchemaName;
return (dbContext, scope);
}
// Usage in tests:
await using var (dbContext, scope) = CreateDbContext();
// ... use dbContext ...
// Both will be disposed automaticallyAlternatively, you could make the scope a field and dispose it in the cleanup method, though the tuple approach is cleaner for this pattern. Why this matters: This is especially important in sample/example code because developers will replicate this pattern. A resource leak in production test suites could accumulate across thousands of tests. Reference: Microsoft EF Core DbContext Lifetime Documentation Otherwise, the PR looks great! The per-test schema isolation pattern is well-designed and the documentation is thorough. This is a valuable addition to the TUnit examples. |
Adds an official example showing how to use EF Core Code First with WebApplicationFactory, TestContainers PostgreSQL, and per-test schema isolation. Each test gets a unique PostgreSQL schema via GetIsolatedName, with tables created by EF Core's EnsureCreatedAsync and cleaned up via DROP SCHEMA CASCADE. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
559c8a2 to
8602b54
Compare
Move schema reading into DbContext constructor via IConfiguration, eliminating EfCoreDatabaseOptions and per-endpoint schema assignment. Fix IServiceScope leak in CreateDbContext by returning AsyncServiceScope. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without this parameter, DI-resolved DbContext always uses "public" schema, making ConfigureTestConfiguration ineffective for schema isolation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
TUnit.Example.Asp.Net.TestProjectshowing how to integrate EF Core with WebApplicationFactory, TestContainers PostgreSQL, and per-test schema isolationGetIsolatedName("schema"), with tables created byEnsureCreatedAsync()and cleaned up viaDROP SCHEMA CASCADEIModelCacheKeyFactoryto handle EF Core model caching across multiple schemasaspnet.md,complex-test-infrastructure.md, andcookbook.mdCloses #4835
New files
TUnit.Example.Asp.Net/EfCore/TodoDbContext.csHasDefaultSchema()TUnit.Example.Asp.Net/EfCore/SchemaModelCacheKeyFactory.csTUnit.Example.Asp.Net/EfCore/EfCoreDatabaseOptions.csTUnit.Example.Asp.Net.TestProject/EfCore/EfCoreWebApplicationFactory.csTUnit.Example.Asp.Net.TestProject/EfCore/EfCoreTodoTestBase.csTUnit.Example.Asp.Net.TestProject/EfCore/EfCoreTodoApiTests.csTest plan
dotnet build)dotnet run --project TUnit.Example.Asp.Net.TestProject -- --treenode-filter "/*/*/EfCoreTodoApiTests/*"ParallelTests_AreIsolatedwith[Repeat(3)]) passes without data leaks🤖 Generated with Claude Code