MS test + EF(VS2008):运行所有测试时:关于不同ObjectContexts的错误

时间:2012-06-28 08:39:50

标签: c# entity-framework visual-studio-2008 mstest

在Visual Studio 2008,C#,Entity Framework 3.5,MS Test中,我有两个测试:

[TestMethod]
public void Test1()
{
    using (Entities context = new Entities())
    {
        using (TransactionHelper transaction = new TransactionHelper(context))
        {
            // Stuff

            transaction.Rollback();
        }
    }
}

[TestMethod]
public void Test2()
{
    using (Entities context = new Entities())
    {
        using (TransactionHelper transaction = new TransactionHelper(context))
        {
            // Stuff

            transaction.Rollback();
        }
    }
}

单独运行时,它们都会通过。但是当我运行所有测试时,它会在第二次测试中说明以下内容:

  

System.InvalidOperationException:两者之间的关系   无法定义对象,因为它们附加到不同的对象   ObjectContext对象..

我根本不明白这一点。在代码路径中没有任何地方可以创建新的Entities对象。我检查过几次(看看代码如何在单独的测试运行中运行生产使用,这一定是真的)。我甚至将实体包装在一个使用声明中。

或许在TestContext中有一些奇怪的保留吗?

作为参考,TransactionHelper(简化):

public class TransactionHelper : IDisposable
{
    private global::System.Data.Objects.ObjectContext _context;
    private ConnectionState _initialConState;
    private DbTransaction _transaction;

    public TransactionHelper(global::System.Data.Objects.ObjectContext context)
    {   
        _context = context;
        _initialConState = context.Connection.State;

        if (_initialConState != ConnectionState.Open)
        {
            _context.Connection.Open(); // open connection if not already open
        }

        _transaction = _context.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
    }

    public void Rollback()
    {
        _transaction.Rollback();
    }

    public void Commit()
    {
        _transaction.Commit();
    }

    public void Dispose()
    {
        _transaction.Dispose();

        if (_initialConState != ConnectionState.Open)
        {
            _context.Connection.Close(); // only close connection if not initially open
        }
    }
}

如果我使用隔离级别ReadCommitted,则没有区别。

1 个答案:

答案 0 :(得分:1)

由于单元测试理想情况下应完全相互独立(在状态,顺序等方面),因此Visual Studio和其他测试框架(如NUnit)可以通过并行运行来加快执行过程。在像你这样的情况下,共享的静态资源通常会成为我的罪魁祸首。

可能是您提到的这些简单对象(例如一些查找值)被分配给实体对象的属性,然后在第二个测试中将同一个简单对象分配给另一个上下文的实体,这会引发像你提到的错误。

如果是这种情况,那么您可以尝试在测试中模拟缓存(或者可以最小化static的使用。)