【发布时间】:2012-04-30 20:56:45
【问题描述】:
在研究 EF 和 Code First 时,我不久前提出了一个问题 (ref this thread),以提醒您如何防止测试相互重叠。我想为数据库播种,并且对每个测试类都这样做(使用 MSTest):
public class CustomerSmokeTests {
private const string CONNECTION_STRING = "server=localhost;database=CPT_CustomerDataSync_SmokeTests;uid=sa;pwd=Password1!;";
private DatabaseFactory _dbfactory;
private CustomerCacheContext _customerContext;
[TestInitialize]
public void Setup() {
// set initializer to create new DB
Database.SetInitializer(new SmokeTestCreateDbWithDataIfNotExists());
Database.SetInitializer(new SmokeTestDropCreateDbWithDataAlways());
// create new DB connection to local SQL Server
_dbfactory = new DatabaseFactory(CONNECTION_STRING);
// connect to DB to auto generate it
_customerContext = _dbfactory.GetDataContext();
}
[TestCleanup]
public void Cleanup() {
_customerContext.Dispose();
_dbfactory.Dispose();
}
// tests
}
但是这里的问题是每个测试都会创建/拆除数据库(不理想,因为它们相互重叠并失败......如果您单独运行测试,它们都会按需要通过......而且这会大大减慢测试)。
一个good solution was to instead wrap them up in TransactionalScopes,但是我想确保在测试运行开始时,使用种子信息重新生成数据库(因为种子在我的开发人员开发的测试中发生变化)。
执行此操作的蛮力方法是在测试初始化中创建某种处理程序,它会检查数据库是否是最近创建的,如果不是,则使用种子信息创建它。如果不是,它将忽略该步骤。然后它会创建一个 TransactionalScope() 将在测试清理中回滚。
但是有没有更好的方法来处理这个问题?对这种蛮力方法有过度设计的感觉...想法?
【问题讨论】:
-
实体框架已经在 savechanges 上使用了幕后事务
标签: unit-testing entity-framework-4.1 ef-code-first