使用事务进行单元测试:多语句事务中不允许使用CREATE DATABASE语句

时间:2014-11-18 14:39:16

标签: entity-framework unit-testing transactions

我有单元测试的基类:

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语句

'奇怪'事情是,当我第二次运行测试时,它会通过。

1 个答案:

答案 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回滚。