从 DI 中删除 DbContext。使用 WebApplicationFactory<Startup> 进行测试
Remove DbContext from DI. Testing with WebApplicationFactory<Startup>
场景为.net core 5 WebAPI,services.AddDbContext在Startup.csConfigureServices中使用,添加SQL服务器。测试使用了MVC测试提供的WebApplicationFactory,我想把DbContext换成InMemory或者指向一个测试数据库。
我曾尝试在 WebApplicationFactory ConfigureWebHost 中将其删除,但 SQL DbContext 仍然存在某些问题,因为在测试运行时,它会访问 SQL 服务器而不是 InMemory 数据库尽管 SQL DbContext 不在 DI 中。
builder.ConfigureTestServices(
services =>
{
var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(DbContext));
if (serviceDescriptor != null)
{
services.Remove(serviceDescriptor);
}
}
测试项目中Startup.cs添加的DbContext有没有正确的替换方式?
找到解决方案。
您必须删除从 DbContext 派生的 class 和所有 DbContextOptions。
例子
services =>
{
var context = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(MyDbContext));
if (context != null)
{
services.Remove(context);
var options = services.Where(r => (r.ServiceType == typeof(DbContextOptions))
|| (r.ServiceType.IsGenericType && r.ServiceType.GetGenericTypeDefinition() == typeof(DbContextOptions<>))).ToArray();
foreach (var option in options)
{
services.Remove(option);
}
}
services.AddDbContext<MyDbContext>(opt => opt.UseInMemoryDatabase(@"TestDB"));
});
场景为.net core 5 WebAPI,services.AddDbContext在Startup.csConfigureServices中使用,添加SQL服务器。测试使用了MVC测试提供的WebApplicationFactory,我想把DbContext换成InMemory或者指向一个测试数据库。
我曾尝试在 WebApplicationFactory ConfigureWebHost 中将其删除,但 SQL DbContext 仍然存在某些问题,因为在测试运行时,它会访问 SQL 服务器而不是 InMemory 数据库尽管 SQL DbContext 不在 DI 中。
builder.ConfigureTestServices(
services =>
{
var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(DbContext));
if (serviceDescriptor != null)
{
services.Remove(serviceDescriptor);
}
}
测试项目中Startup.cs添加的DbContext有没有正确的替换方式?
找到解决方案。 您必须删除从 DbContext 派生的 class 和所有 DbContextOptions。
例子
services =>
{
var context = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(MyDbContext));
if (context != null)
{
services.Remove(context);
var options = services.Where(r => (r.ServiceType == typeof(DbContextOptions))
|| (r.ServiceType.IsGenericType && r.ServiceType.GetGenericTypeDefinition() == typeof(DbContextOptions<>))).ToArray();
foreach (var option in options)
{
services.Remove(option);
}
}
services.AddDbContext<MyDbContext>(opt => opt.UseInMemoryDatabase(@"TestDB"));
});