11using Clean . Architecture . Infrastructure . Data ;
2+ using Microsoft . EntityFrameworkCore ;
3+ using Testcontainers . MsSql ;
24
35namespace Clean . Architecture . FunctionalTests ;
46
5- public class CustomWebApplicationFactory < TProgram > : WebApplicationFactory < TProgram > where TProgram : class
7+ public class CustomWebApplicationFactory < TProgram > : WebApplicationFactory < TProgram > , IAsyncLifetime where TProgram : class
68{
9+ private readonly MsSqlContainer _dbContainer = new MsSqlBuilder ( )
10+ . WithImage ( "mcr.microsoft.com/mssql/server:2022-latest" )
11+ . WithPassword ( "Your_password123!" )
12+ . Build ( ) ;
13+
14+ public async Task InitializeAsync ( )
15+ {
16+ await _dbContainer . StartAsync ( ) ;
17+ }
18+
19+ public new async Task DisposeAsync ( )
20+ {
21+ await _dbContainer . DisposeAsync ( ) ;
22+ }
23+
724 /// <summary>
825 /// Overriding CreateHost to avoid creating a separate ServiceProvider per this thread:
926 /// https://github.com/dotnet-architecture/eShopOnWeb/issues/465
@@ -12,7 +29,7 @@ public class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProg
1229 /// <returns></returns>
1330 protected override IHost CreateHost ( IHostBuilder builder )
1431 {
15- builder . UseEnvironment ( "Development " ) ; // will not send real emails
32+ builder . UseEnvironment ( "Testing " ) ; // will not send real emails
1633 var host = builder . Build ( ) ;
1734 host . Start ( ) ;
1835
@@ -29,21 +46,13 @@ protected override IHost CreateHost(IHostBuilder builder)
2946 var logger = scopedServices
3047 . GetRequiredService < ILogger < CustomWebApplicationFactory < TProgram > > > ( ) ;
3148
32- // Reset Sqlite database for each test run
33- // If using a real database, you'll likely want to remove this step.
34- db . Database . EnsureDeleted ( ) ;
35-
36- // Ensure the database is created.
37- db . Database . EnsureCreated ( ) ;
38-
3949 try
4050 {
41- // Can also skip creating the items
42- //if (! db.ToDoItems.Any())
43- //{
51+ // Apply migrations to create the database schema
52+ db . Database . Migrate ( ) ;
53+
4454 // Seed the database with test data.
4555 SeedData . PopulateTestDataAsync ( db ) . Wait ( ) ;
46- //}
4756 }
4857 catch ( Exception ex )
4958 {
@@ -60,26 +69,22 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
6069 builder
6170 . ConfigureServices ( services =>
6271 {
63- // Configure test dependencies here
64-
65- //// Remove the app's ApplicationDbContext registration.
66- //var descriptor = services.SingleOrDefault(
67- //d => d.ServiceType ==
68- // typeof(DbContextOptions<AppDbContext>));
69-
70- //if (descriptor != null)
71- //{
72- // services.Remove(descriptor);
73- //}
72+ // Remove the app's ApplicationDbContext registration
73+ var descriptors = services . Where (
74+ d => d . ServiceType == typeof ( AppDbContext ) ||
75+ d . ServiceType == typeof ( DbContextOptions < AppDbContext > ) )
76+ . ToList ( ) ;
7477
75- //// This should be set for each individual test run
76- //string inMemoryCollectionName = Guid.NewGuid().ToString();
78+ foreach ( var descriptor in descriptors )
79+ {
80+ services . Remove ( descriptor ) ;
81+ }
7782
78- //// Add ApplicationDbContext using an in-memory database for testing.
79- // services.AddDbContext<AppDbContext>(options =>
80- // {
81- // options.UseInMemoryDatabase(inMemoryCollectionName );
82- // });
83+ // Add ApplicationDbContext using the Testcontainers SQL Server instance
84+ services . AddDbContext < AppDbContext > ( ( provider , options ) =>
85+ {
86+ options . UseSqlServer ( _dbContainer . GetConnectionString ( ) ) ;
87+ } ) ;
8388 } ) ;
8489 }
8590}
0 commit comments