2013-04-26 82 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