我有一个首先使用EF代码的代码,我想在单元测试中进行单元测试我想在测试开始时使用真正的空数据库,所以我做了:
[TestInitialize]
public void Initialize()
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
}
[TestCleanup]
public void CleanUp()
{
MyContext db = new MyContext();
db.Database.Delete();
}
但是由于测试并行运行,这不起作用所以我用我的测试进行了订单测试 有问题,因为数据库有时不会因为正在使用而被删除... 有人有更好的策略吗?我想也许每个测试都会创建自己的数据库?如果这是个好主意我怎么能实现这个目标呢?
答案 0 :(得分:1)
请试试这个
[TestClass]
public class UnitTestClass
{
private static string testConnString;
[TestInitialize]
public void Initialize()
{
testConnString = GetTestConnString();
using (MyContext db = new MyContext(testConnString, new DropCreateDatabaseAlways<MyContext>()))
{
db.UnderlyingContext.Connection.Open();
}
}
[TestMethod]
public void TestMethod1()
{
}
[TestCleanup]
public void CleanUp()
{
using (MyContext db = new MyContext(testConnString))
{
db.Database.Delete();
}
}
private static string GetTestConnString()
{
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
csb.DataSource = @"MYPC\SQLEXPRESS"; // Replace it with your SQL-server name
csb.InitialCatalog = "DB"+Guid.NewGuid().ToString().Replace("-","");
csb.IntegratedSecurity = true;
return csb.ToString();
}
}
public class MyContext : DbContext
{
private static IDatabaseInitializer<MyContext> _Initializer;
public MyContext(string connString, IDatabaseInitializer<MyContext> initializer = null)
: base(connString)
{
_Initializer = initializer;
}
public ObjectContext UnderlyingContext
{
get { return (this as IObjectContextAdapter).ObjectContext; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (_Initializer != null)
{
Database.SetInitializer(_Initializer);
}
base.OnModelCreating(modelBuilder);
}
}
答案 1 :(得分:1)
&#34;真实&#34;意思?您是否考虑过在单元测试中使用内存数据库?使用像SQLite这样的内存数据库,您可以为每个测试设置一个新的数据库,而开销相对较小。您还可以准备一次测试数据库,将其存储到文件中,然后为每个测试加载它。查看this answer。并且this link。如果你谷歌一点,你会发现更多。
我会尽量避免依赖订购。测试应该彼此独立,以便从失败的测试到代码中的问题实现清晰的可追溯性。测试不应该只因为另一个测试操纵共享数据而失败。
另一个问题是我的表现。通过强制排序并行测试执行是不可能的。如果您为所有测试使用类似生产的数据库设置,它们肯定比内存替换慢得多。