NUnit TestFixure和SetUp的嵌套TransactionScope

Lea*_*Dev 7 c# sql nunit unit-testing transactions

我派生自这个基类,以便将每个单独的测试封装到一个回滚的事务中

public abstract class TransactionBackedTest
{
    private TransactionScope _transactionScope;

    [SetUp]
    public void TransactionSetUp()
    {
        var transactionOptions = new TransactionOptions
        {
            IsolationLevel = IsolationLevel.ReadCommitted,
            Timeout = TransactionManager.MaximumTimeout
        };

        _transactionScope = new TransactionScope(TransactionScopeOption.Required, 
                                                 transactionOptions);
    }

    [TearDown]
    public void TransactionTearDown()
    {
        _transactionScope.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这个我也尝试以相同的方式设置TestFixure事务:

[TestFixture]
class Example: TransactionBackedTest
{

    private TransactionScope _transactionScopeFixure;


    [TestFixtureSetUp]
    public void Init()
    {
        var transactionOptions = new TransactionOptions
        {
            IsolationLevel = IsolationLevel.ReadCommitted,
            Timeout = TransactionManager.MaximumTimeout
        };

        _transactionScopeFixure = new TransactionScope(TransactionScopeOption.Required,
                                                       transactionOptions);


        SetupAllDataForAllTest();
    }

    [TestFixtureTearDown]
    public void FixtureTearDown()
    {
        _transactionScopeFixure.Dispose();
    }


    public void SetupAllDataForAllTest()
    {
        // Sql stuff here that will get undone from the TestFixtureTearDown scope dispose
    }


    [Test]
    public void DoSqlStuff1()
    {
        // Sql stuff here that will get undone from the TransactionBackedTest
    }

    [Test]
    public void DoSqlStuff2()
    {
        // Sql stuff here that will get undone from the TransactionBackedTest
    }
}
Run Code Online (Sandbox Code Playgroud)

这个想法是SetupAllDataForAllTest在开始时运行一次并插入测试所依赖的所有基础数​​据.测试完成后,需要删除/回滚此基础数据.

我也希望每个测试都是隔离的,这样它们也不会互相干扰.

我现在遇到的问题是,在第一次测试之后,它表明TestFixture事务已经关闭,即使我只希望它关闭SetUp事务.我的假设是,如果你Dispose()和内部交易它是外部的,那么我不知道如何完成我想做的事情

Vla*_*nov 4

你没说你用什么数据库。

在 MS SQL Server 中,如果您BEGIN TRANSACTION在另一个事务内部(使它们嵌套),然后ROLLBACK TRANSACTION在嵌套事务内部,它将回滚所有内容(以及整个外部事务)。

没有 savepoint_name 或 transaction_name 的 ROLLBACK TRANSACTION 将回滚到事务的开头。当嵌套事务时,同一语句将所有内部事务回滚到最外层的 BEGIN TRANSACTION 语句。

为了能够仅回滚内部嵌套事务,应该以SAVE TRANSACTION <name>嵌套事务的某个名称来启动。然后您可以ROLLBACK <name>仅回滚嵌套部分。

如果您使用其他数据库,它在嵌套事务中的行为可能会有所不同。

我不知道如何让你的类BEGIN or SAVE TRANSACTION根据事务是否嵌套来发出正确的 SQL 语句。