在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
,则没有区别。
答案 0 :(得分:1)
由于单元测试理想情况下应完全相互独立(在状态,顺序等方面),因此Visual Studio和其他测试框架(如NUnit)可以通过并行运行来加快执行过程。在像你这样的情况下,共享的静态资源通常会成为我的罪魁祸首。
可能是您提到的这些简单对象(例如一些查找值)被分配给实体对象的属性,然后在第二个测试中将同一个简单对象分配给另一个上下文的实体,这会引发像你提到的错误。
如果是这种情况,那么您可以尝试在测试中模拟缓存(或者可以最小化static
的使用。)