Entity framework 使用事务处理与实体框架集成测试的缺点
我正在寻找一种快速的方法来清理我的数据表,使用EF进行集成测试 每个人似乎都会围绕其测试方法包装一个事务,并在测试后处理该事务 这样,数据就不会写入表中 新的插入自动ID等功能仍在运行,但我问自己,与.commit()事务相比,这种方法是否真的可靠 使用这种方法是否有任何缺点,因为它似乎不是一个真正的集成测试,因为数据库从未接触过 或者换言之,是否存在使用不带commit()的事务不会作为异常弹出的错误场景 更新Entity framework 使用事务处理与实体框架集成测试的缺点,entity-framework,transactions,entity-framework-6.1,Entity Framework,Transactions,Entity Framework 6.1,我正在寻找一种快速的方法来清理我的数据表,使用EF进行集成测试 每个人似乎都会围绕其测试方法包装一个事务,并在测试后处理该事务 这样,数据就不会写入表中 新的插入自动ID等功能仍在运行,但我问自己,与.commit()事务相比,这种方法是否真的可靠 使用这种方法是否有任何缺点,因为它似乎不是一个真正的集成测试,因为数据库从未接触过 或者换言之,是否存在使用不带commit()的事务不会作为异常弹出的错误场景 更新 public abstract class IntegrationTestsBas
public abstract class IntegrationTestsBase
{
protected TransactionScope TransactionScope;
public abstract void TestSetup();
protected void InitTestSetupOnTable(string tableName)
{
TransactionScope = new TransactionScope();
using (var context = new TGBContext())
{
var cmdCommand = string.Format("DBCC CHECKIDENT ({0}, RESEED, 1)", tableName);
context.Database.ExecuteSqlCommand(cmdCommand);
context.SaveChanges();
}
}
[TestCleanup]
public void TestCleanup()
{
TransactionScope.Dispose();
}
}
[TestClass]
public class MyTests : IntegrationTestsBase
{
[TestInitialize]
public override void TestSetup()
{
base.InitTestSetupOnTable("MyTableName");
}
}
因为数据库从未被触碰过
肯定是感动了。事务中发生的一切都发生在数据库中。标识值和序列(如果有)递增、触发、检查引用约束等。唯一的问题是,它是孤立发生的,最终所有内容(递增的标识和序列除外)都被还原
使用这种方法有什么缺点吗
不是真的。我在自己的代码中广泛使用了这种方法,它有很多优点。绿色测试提供了非常高的保证级别。使用模拟上下文和DbSet
的“真实”单元测试,我永远不会感到安全(尽管我在许多其他事情上使用单元测试)
但是有一些限制你应该注意
- 标识/序列值不是确定性的,因此不能断言它们。正如我所说,这些值不会被回滚。如果您在该区域确实需要断言,您可以在每次测试后重置标识/序列
- 我们无法用这种方法测试并发性问题
- 如果没有DTC,您无法打开到另一个数据库的连接,或者如果其连接字符串在最细微的细节(例如,不同的应用程序名称或不同的MARS设置)上存在差异,甚至无法打开到同一个数据库的连接。在应用程序代码中,这是可能的,因为这些不同的调用不会包装在
中。因此,可能不是所有的应用程序路径都可以通过这种方式轻松测试TransactionScope
- 开发人员应该使用自己的测试数据库副本。如果多个开发人员(可能还有一个构建服务器)在同一个数据库上运行测试,他们可能会互相死锁