Lie*_*ero 5 unit-testing entity-framework dependency-injection entity-framework-core .net-core
我想在每个单元测试中创建干净的内存数据库。当我运行多个测试时,以前测试中的数据仍保留在数据库中。如何处理现有的内存数据库?
我使用以下代码初始化每个测试:
[TestInitialize]
public void TestInitialize()
{
Services = new ServiceCollection();
Services.AddScoped<DbContextOptions<MyDbContext>>(sp => new DbContextOptionsBuilder<TacsDbContext>()
.UseInMemoryDatabase("MyTestDbContext")
.Options);
Services.AddTransient<InMemoryMyDbContext>();
Services.AddTransient<MyDbContext>(sp => sp.GetService<InMemoryTacsDbContext>());
ServiceProvider = Services.BuildServiceProvider();
}
[TestMethod]
public void Test1()
{
using (var dbContext = ServiceProvider.GetService<MyDbContext>()) ...
}
[TestMethod]
public void Test2()
{
using (var dbContext = ServiceProvider.GetService<MyDbContext>()) ...
}
Run Code Online (Sandbox Code Playgroud)
我使用.NET Core 2.0和Entity Framework Core 2.0
编辑
我无法使用标准注册:Services.AddDbContext<InMemoryMyDbContext>(...),因为
public class InMemoryMyDbContext : MyDbContext
{
public InMemoryMyDbContext(DbContextOptions<InMemoryMyDbContext> options)
: base(options) { } //compiler error
public InMemoryMyDbContext(DbContextOptions<MyDbContext> options)
: base(options) { } //runtime IoC error
}
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options) { }
}
Run Code Online (Sandbox Code Playgroud)
好的,我的例子的解决方案是调用DbContextOptionsBuilder.UseApplicationServiceProvider()
Services.AddScoped<DbContextOptions<MyDbContext>>(sp => new DbContextOptionsBuilder<MyDbContext>()
.UseApplicationServiceProvider(sp)
.UseInMemoryDatabase("Test")
.Options);
Run Code Online (Sandbox Code Playgroud)
当您以通常的方式设置 ServiceCollection 时,会自动调用此方法,因此在以下情况下,每次都会从头开始创建数据库
Services.AddDbContext<MyDbContext>(options => options.UseInMemoryDatabase("Test"));
Run Code Online (Sandbox Code Playgroud)
最后,我能够修改 MyDbContext 以便调用上面的行:
public class MyDbContext : DbContext
{
protected MyDbContext (DbContextOptions options) : base(options) { }
public MyDbContext (DbContextOptions<MyDbContext> options)
: this((DbContextOptions)options) { }
}
public class InMemoryMyDbContext : MyDbContext
{
public InMemoryMyDbContext (DbContextOptions<InMemoryTacsDbContext> options)
: base(options) { }
}
Services.AddDbContext<InMemoryMyDbContext>(options =>
options.UseInMemoryDatabase("Test"), ServiceLifetime.Transient);
Services.AddTransient<MyDbContext>(sp => sp.GetService<InMemoryMyDbContext>());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2017 次 |
| 最近记录: |