2013-05-06 41 views
1

我一直在讀了一堆關於文章嘲笑我的倉庫模式EF 5和我的一些問題感到困惑的幾件事情:上嘲諷EF 5和測試存儲庫模式

我有一個經理級帶方法說AddCat(string name);。該方法確保name有效,並在我的CatRepository上調用AddCat(string name)CatRepository只是myContext.Cats.Add(new Cat() { Name = name });

我相信是簡單的存儲庫模式。

  • 我應該將資源庫傳遞到Manager類中,以便稍後對其進行單元測試,或者我應該測試資源庫?

  • 我想傳遞一個上下文到我的資料庫,所以我可以單元測試它。所以我會創建一個接口IMyContext但我不確定如何獲得EF上下文來實現它 - 因爲我添加它的地方是在自動生成的代碼中,我擔心它只會將其擦除。有沒有其他方法讓我將自定義上下文傳遞給存儲庫?

回答

5

我應該通過存儲庫到Manager類,所以我可以在以後 單元測試,或者我應該只是測試庫?

您應該單獨測試每個類。你的經理類包含實際的業務邏輯,所以你可能要測試幾種情況:

  • 有效的名稱
  • 無效的名稱
  • 空的名字

你要確保CatRepository.Add是當名稱無效時不會調用,並且在有效時使用正確的名稱調用它。要達到此目的,請確保您的Manager類與接口ICatRepository一起使用。在你的單元測試中,你使用了一種名爲mocking的技術來將你的ICatRepository的虛假實現傳遞給你的管理器類。該模擬具有特殊的功能,可以讓你檢查哪些方法調用和驗證這些方法的參數。

這意味着你的經理不應該構建CatRepository本身:

// Not a good solution 
public class Manager 
{ 
    public Manager() 
    { 
     this.catRepository = new CatRepository(); 
    } 
} 

這種方式,你有沒有與你的嘲笑版本替換CatRepository的方式。相反,你應該使用一種稱爲依賴注入:

// Seperate construction from business logic 
public class Manager 
{ 
    public Manager(ICatRepository catRepository) 
    { 
     this.catRepository = catRepository; 
    } 
} 

CatRepository不包含任何實際的邏輯。您可以使用集成測試(運行速度較慢的使用真實數據庫或其他外部對象的測試)來確保您的存儲庫正常運行。

我寫了一個大約一年前,圍繞這一主題博客,解釋一體化和單元測試,以及如何嘲諷可以幫助你創造了良好的單元測試的區別:Unit Testing, hell or heaven?

我想傳遞一個上下文到我的存儲庫,所以我可以單元測試它。所以 我會創建一個接口IMyContext,但我不知道如何獲得EF 上下文來實現它 - 作爲我添加它的地方是在自動生成的 代碼,我擔心它只是將其擦除。有沒有其他方法可以讓 將自定義上下文傳遞給存儲庫?

您的上下文生成爲partial classPartial表示您的課程可以分散在多個.cs文件中。編譯器將這些文件合併在一起併爲其輸出一個類。這樣你可以有一個由EF自動生成的.cs文件和另一個實現你的界面的文件。事情是這樣的:

mycontext.cs

public partial class MyContext : ObjectContext 
{ } 

mycontextinterface.cs

public interface IMyContext {} 

public partial class MyContext : IMyContext 
{ } 
+0

優秀非常感謝你對這個答覆,它回答了我所有的問題! :) – NibblyPig 2013-05-06 10:37:18

+0

你知道我應該在我的界面中使用什麼數據類型嗎?由於MyContext具有'public DbSet Cats {get;組; }'我不認爲我想讓我的界面使用DbSet。 IEnumerable會很好,但它說沒有實現。除非我在部分課程中編寫包裝。 – NibblyPig 2013-05-06 11:56:37

+0

您可以公開IDbSet屬性。那個是由DbSet實現的。您絕對不希望將所有DbSets轉換爲IEnumerable,因爲那樣您將失去將Linq To Entity查詢轉換爲SQL並將工作轉移到數據庫的能力。 DbContext是一個低級別的對象,僅用於集成測試,將其進一步抽象爲「單元測試」是沒有意義的。微軟已經有EF的單元測試:) – 2013-05-06 18:43:09