roc*_*sen 9 c# integration-testing asp.net-core
我正在尝试按照文档为 aspnetcore v6 webapi 添加一些集成测试 - https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0#aspnet-core -集成测试。
我的 webapi 数据库是 SQLServer。我希望针对实际的 SQLServer 数据库而不是内存数据库运行测试。我遇到了 dotnet-testcontainers - https://github.com/HofmeisterAn/dotnet-testcontainers并考虑使用它,这样我就不需要担心重置数据库,因为一旦运行测试,容器就会被删除。
这就是我打算做的:
这样我就可以启动连接到容器中运行的干净数据库的测试 Web 主机,运行测试。
这种方法听起来正确吗?或者是否有人使用 dotnet-testcontainers 来启动容器以进行应用程序测试以及哪种方法有效。
Mat*_*tze 11
我在这里写了关于这种方法的文章。
您基本上需要创建一个自定义WebApplicationFactory连接字符串,并将数据库上下文中的连接字符串替换为指向测试容器的连接字符串。
这是一个示例,只需要稍微调整即可匹配 MSSQL docker 映像。
public class IntegrationTestFactory<TProgram, TDbContext> : WebApplicationFactory<TProgram>, IAsyncLifetime
where TProgram : class where TDbContext : DbContext
{
private readonly TestcontainerDatabase _container;
public IntegrationTestFactory()
{
_container = new TestcontainersBuilder<PostgreSqlTestcontainer>()
.WithDatabase(new PostgreSqlTestcontainerConfiguration
{
Database = "test_db",
Username = "postgres",
Password = "postgres",
})
.WithImage("postgres:11")
.WithCleanUp(true)
.Build();
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestServices(services =>
{
services.RemoveProdAppDbContext<TDbContext>();
services.AddDbContext<TDbContext>(options => { options.UseNpgsql(_container.ConnectionString); });
services.EnsureDbCreated<TDbContext>();
});
}
public async Task InitializeAsync() => await _container.StartAsync();
public new async Task DisposeAsync() => await _container.DisposeAsync();
}
Run Code Online (Sandbox Code Playgroud)
以下是替换和初始化数据库上下文的扩展方法。
public static class ServiceCollectionExtensions
{
public static void RemoveDbContext<T>(this IServiceCollection services) where T : DbContext
{
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<T>));
if (descriptor != null) services.Remove(descriptor);
}
public static void EnsureDbCreated<T>(this IServiceCollection services) where T : DbContext
{
var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var scopedServices = scope.ServiceProvider;
var context = scopedServices.GetRequiredService<T>();
context.Database.EnsureCreated();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10481 次 |
| 最近记录: |