项目中是用VS自带的单元测试框架,也不想因为这一个特性而改用xunit,那只能动手把这个迁移到VS的单元测试框架里了。

/// <summary>
/// 单元测试基类
/// </summary>
[TestClass]
public class BaseUnitTest
{
    IsolationLevel _isolationLevel = IsolationLevel.Unspecified;
    TransactionScopeOption _scopeOption = TransactionScopeOption.Required;
    TransactionScope _transactionScope;
    bool _openAutoRollback = true;

     /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="autoRollback">是否开启自动回滚,默认开启</param>
    public BaseUnitTest(bool autoRollback = true)
    {
        _openAutoRollback = autoRollback;
    }

     /// <summary>
    /// 自动回滚事务初始化
    /// </summary>
    [TestInitialize]
    public void AutoRollbackBefore()
    {
        if (_openAutoRollback)
        {
            var options = new TransactionOptions();
            options.IsolationLevel = _isolationLevel;
            options.Timeout = new TimeSpan(0, 1, 0);
            _transactionScope = new TransactionScope(_scopeOption, options);
        }
    }

     /// <summary>
    /// 自动回滚事务回滚并释放对象
    /// </summary>
    [TestCleanup]
    public void AutoRollbackAfter()
    {
        if (_openAutoRollback)
        {
            if (_transactionScope == null)
                throw new InvalidOperationException("未初始化TransactionScope");
            //回滚事务
            _transactionScope.Dispose();
            //释放事务对象
            _transactionScope = null;
            //移除所有的缓存
            RemoveHttpRuntimeCache();
        }
    }

     /// <summary>
    /// 移除所有的HttpRuntime缓存
    /// </summary>
    [DebuggerStepThrough]
    private void RemoveHttpRuntimeCache()
   {
        var cache = HttpRuntime.Cache.GetEnumerator();
        var keys = new List<string>();
        while (cache.MoveNext())
        {
            keys.Add(cache.Key.ToString());
        }
        foreach (var key in keys)
        {
            HttpRuntime.Cache.Remove(key);
        }
    }

     /// <summary>
    /// 设置不自动回滚事务
    /// </summary>
    protected void SetAutoRollbackIsUnavailabled()
    {
        _openAutoRollback = false;
    }
}

  上面的RemoveHttpRuntimeCache是因为我们在项目中有使用HttpRuntime缓存,关系数据库中的数据回滚后会导致缓存和数据库不一致,所以一但有开启事务的自动回滚,也要相应的清空内存缓存。

  方法很简单,跟大家分享一下,和TransactionScope相关的知识,不清楚的同学可以看下MSDN关于“TransactionScope”的文档。