2013-04-26 68 views
2

我想使用EntityFramework 5,SQL Server Compact 4和Xunit来设置一些单元测试。在单元测试中重用DbContext实例之间的连接

我使用不同的上下文实例,因为我测试一个ASP MVC应用程序,我需要通过分离的实体来测试一些更新操作的行为。

[Fact, AutoRollback] 
public void TestConnection() 
{ 
    using (var connection = this.GetDbConnection()) 
    { 
     using (var context = new MyContext(connection, false)) 
     { 
      // Do database stuff 
     } 

     using (var context = new MyContext(connection, false)) 
     { 
      // Do database stuff 
     } 
    } 
} 

public DbConnection GetDbConnection() 
{ 
    string dataSource = "|DataDirectory|\\MyDb.sdf"; 

    var sqlBuilder = new SqlCeConnectionStringBuilder(); 
    sqlBuilder.DataSource = dataSource; 

    return new SqlCeConnection(sqlBuilder.ToString()); 
} 

这给了我下面的错误:

System.Data.EntityException : The underlying provider failed on Open. 
System.InvalidOperationException : The connection object can not be enlisted in transaction scope. 

我知道我不能打开多个DbContext实例的TransactionScope内(也就是当你把一个FallbackAttribute在方法的xUnit做大概是什么) ,所以这就是为什么我要事先创建连接。

如果我尝试打开连接自己,它仍然不能正常工作:

using (var connection = this.GetDbConnection()) 
{ 
    connection.Open(); 

    using (var context = new MyContext(connection, false)) 
    { 

我得到以下异常:

System.ArgumentException : EntityConnection can only be constructed with a closed DbConnection. 

任何一个人知道如何解决这个问题?

编辑

的测试类,与数据库处理扩展在数据库初始化为下面一个 “DomainFactsBase”:

public DomainFactsBase() 
{ 
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>()); 
    using (var context = new MyContext(GetDbConnection(), true)) 
     context.Database.Initialize(false); 
} 

编辑

我能成功地当我仅创建一个上下文实例时,使用自动回滚运行测试。这是按照this article中的说明完成的。我有一个扩展方法:

public static void OpenConnection(this DbContext context) 
{ 
    ((IObjectContextAdapter)context).ObjectContext.Connection.Open(); 
} 

,我把它称为创造了测试上下文之后:

[Fact, AutoRollback] 
public void SomeFact() 
{ 
    using (var context = new MyContext()) 
    { 
     context.OpenConnection(); 

      // Do stuff 
    } 
} 

也就是说,没有任何问题的工作。当我尝试在相同的事实中启用不止一次的打开环境(启用AutoRollback)时,它们就会出现,正如我在开始时所展示的那样。

回答

1

初始化测试以外的数据库。你可以在测试类的构造函数中做到这一点。

public MyTestClass() 
{ 
    using (var db = new MyContext(GetDbConnection(), true)) 
    { 
     db.Database.Initialize(false); 
    } 
} 
+0

谢谢布莱斯,但我所有的数据库测试类扩展,其中如你所说的数据库初始化的“DomainFactsBase”级。 – 2013-05-24 16:11:41