c# - 如何在测试 ASP.NET Core 应用程序时使用 EF Core 使用 InMemory 数据库将数据播种到 DbContext?
问题描述
您好,我的应用程序中包含一些集成测试。在实例化测试类时,我正在使用以下类准备数据库:
internal static class DatabaseTestPreparation
{
private const string TestDatabaseName = "TestDatabase";
internal static IServiceCollection ConfigureTestDatabases(this IServiceCollection services) =>
services
.PrepareTestDatabaseContext<EventStoreContext>()
.PrepareTestDatabaseContext<GrantContext>();
private static IServiceCollection PrepareTestDatabaseContext<T>(this IServiceCollection services)
where T : DbContext
{
var descriptor = services.SingleOrDefault(service =>
service.ServiceType == typeof(DbContextOptions<T>));
if (!(descriptor is null))
{
services
.Remove(descriptor);
}
services
.AddDbContext<T>(options =>
options.UseInMemoryDatabase(TestDatabaseName))
.Seed<T>();
return services;
}
private static IServiceCollection Seed<T>(this IServiceCollection services) where T : DbContext
{
var serviceProvider = services.BuildServiceProvider();
var dbContext = serviceProvider
.GetService(typeof(T)) as T;
dbContext
?.Database
.EnsureCreated();
return services;
}
}
我的 DbContext 类中还包含一些种子逻辑。例如:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
CreateConstraints(modelBuilder);
SeedInitialData(modelBuilder);
}
private static void CreateConstraints(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PermissionEntity>()
.HasIndex(permission => permission.Code)
.IsUnique();
modelBuilder.Entity<ApplicationEntity>()
.HasIndex(app => app.Name)
.IsUnique();
}
private static void SeedInitialData(ModelBuilder modelBuilder)
{
var application = new ApplicationEntity
{
...
};
modelBuilder.Entity<ApplicationEntity>()
.HasData(application);
var managerRole = new RoleEntity
{
...
};
modelBuilder.Entity<RoleEntity>()
.HasData(managerRole);
var permission = new PermissionEntity
{
...
};
modelBuilder.Entity<PermissionEntity>()
.HasData(permission);
var permissionRoleAssignment = new PermissionRoleAssignmentEntity
{
...
};
modelBuilder.Entity<PermissionRoleAssignmentEntity>()
.HasData(permissionRoleAssignment);
var principal = new PrincipalEntity
{
...
};
modelBuilder.Entity<PrincipalEntity>()
.HasData(principal);
var principalRoleAssignment = new PrincipalRoleAssignmentEntity
{
...
};
modelBuilder.Entity<PrincipalRoleAssignmentEntity>()
.HasData(principalRoleAssignment);
}
上面的这些方法肯定会正确执行,因为我在运行测试时已经用调试器检查了它。问题是,虽然我已经在 DbContext 类中编写了种子方法,但是当某些测试方法运行时,似乎在测试方法中使用的 DbContext 中没有数据。如何正确使用 EF Core InMemoryProvider 播种数据?我究竟做错了什么?
解决方案
推荐阅读
- javascript - Moment.js 格式化时间不正确
- python - 在 django-graphql-jwt 中使用 @login_required 进行查询/突变会导致 graphql.error.located_error.GraphQLLocatedError
- oracle - 如何使用引用器?
- rxjs - 来自源 Observable 的“Bookending”值
- excel - 对于列中的每个值循环遍历表并复制每个实例的行,粘贴到另一个工作表
- reactjs - 在反应中使用 FFmpeg.wasm 处理音频文件时出错:“ffmpeg.FS('readFile', 'output.mp3') 错误。检查路径是否存在”
- r - 数据平均值不接近我选择的年龄
- python - 如果等于另一个熊猫列,则从熊猫列中删除字符串的右侧部分
- python - 使用 matplotlib 在 Python 中绘制时间/值图
- android - android 11中的PDF查看器权限问题