我有单元测试的基类:
public abstract class DatabaseTestsBase
{
protected OvuContext DbContext;
protected TransactionScope TransactionScope;
[SetUp]
public void TestSetup()
{
TransactionScope = new TransactionScope(TransactionScopeOption.RequiresNew);
DbContext = new OvuContext("IntegrationTestContext");
}
[TearDown]
public void TestCleanup()
{
TransactionScope.Dispose();
}
}
测试本身:
[TestFixture]
public class MyEntityTests : DatabaseTestsBase
{
[Test]
public void MyEntity_Create_HasSucceeded()
{
var myEntity = new MyEntity(Guid.NewGuid());
myEntity.Description = "bla bla bla";
var id = myEntity.Id;
DbContext.MyEntities.Add(myEntity);
DbContext.SaveChanges();
var temp = DbContext.MyEntities.Single(x => x.Id == id);
ComparisonResult result = CompareLogic.Compare(myEntity, temp);
Assert.True(result.AreEqual);
}
}
测试运行时出现以下错误: 多语句事务中不允许使用CREATE DATABASE语句
'奇怪'事情是,当我第二次运行测试时,它会通过。
答案 0 :(得分:2)
我相信您正在采用在未提交的事务(例如TransactionScope)下完成的数据库副作用集成/单元测试的模式有点远:)
Code First EF正在尝试在环境TransactionScope
的上下文中创建数据库,这是不可能的。
在Sql Server(以及可能的其他RDBMS')中,it isn't possible to execute certain statements,例如CREATE DATABASE
,在事务下执行命令。如果直接在SSMS中执行以下操作,您将收到相同的错误:
use master;
BEGIN TRAN
CREATE DATABASE FOO;
-- CREATE DATABASE statement not allowed within multi-statement transaction.
我建议您更改策略,以便预先创建一个永久的空测试数据库以进行测试。 EF Code First执行的其他DDL语句(例如CREATE TABLE
)可以由未提交的TransactionScope
回滚。