2012-10-09 49 views
7

我正在嘗試執行tdd並將mongodb用作數據庫。但我不能解決嘲弄MongoDB的問題。在.NET中是否有能力模擬mongodb進行單元測試?.NET中的Mongodb單元測試


更新

我覺得非常好soltion閱讀博客。 你可以找到它here

回答

13

而是嘲諷的MongoDB的,你應該在的MongoDB的頂部嘲諷一層

您可能想要考慮一個接口,該接口公開存儲庫上對底層數據存儲不可知的操作。例如,你可能想抽象出業務上Student類型,像這樣的接口:

public interface IStudentOperations 
{ 
    void Add(Student student); 
} 

當您創建其他的依賴,你注入上面的界面,或者無論你選擇哪個更高層次抽象的實例。

重點是,不要直接暴露MongoDB

一旦你這樣做了,你可以模擬你想創建的所有接口,有一個用於測試模擬實現的實現,然後用它自己的測試來驗證實現上的操作是否正確底層實現是使用MongoDB。

雖然它絕對是possible to mock most of MongoDB's classes (as the methods are virtual),但您獲得持久性不可知的好處;如果你想轉換說CouchDB或elasticsearch,你不必改變對這些接口的調用,你只需創建一個新的實現。


因爲you are trying to test the implementation of the repository,那麼你一般都很好,因爲之前已經指出,大部分的MongoDB的功能是virtual,這是友好的最嘲諷庫。

這就是說,你必須確保你通過MongoDatabase你的倉庫(不是創建它在),以便在單元測試中,你可以創建相應的模擬,然後通過將它存入您的存儲庫實現中進行測試

+0

雖然我casperOne同意,它會由於公共方法是虛擬的,因此可以用大多數模擬框架來模擬MongoDB驅動程序的類。 – kfuglsang

+0

我將使用存儲庫模式。所以我需要模擬All,Save和其他。這就是爲什麼我需要模仿mongo – F0rc0sigan

+0

@kfuglsang更新的答案與直接嘲弄MongoDB的好處。 – casperOne

2

看到這個類似的問題:Mocking database in node.js?

總之,嘲諷MongoDB是不正確的方法。嘲笑你的倉庫對於測試你自己的設備是足夠的,但是如果你想確保你正確地使用它,或者你依賴於唯一性約束等,你仍然需要對MongoDB進行測試。

1

你需要存儲庫/ DAL層來隱藏實現細節。事情是這樣的:

public interface IDataContext<T> 
{ 
    // Query 
    IList<T> GetAll<T>(); 
    IList<T> GetByCriteria<T>(Query query); 
    T GetByID<T>(string id); 

    // CUD 
    void Add(T item); 
    void Delete(T item); 
    void Save(T item); 
} 
  • 對於生產代碼,實現與蒙戈DB操作的接口與C#驅動
  • 的協助下對單元測試代碼,與內存中的集合嘲笑接口

它看起來很簡單,模擬添加/刪除/保存,和intersting部分是查詢功能。幸運的是,由於mongo C#驅動程序支持LINQ表達式,因此我們可以使用LINQ作爲查詢語言,而不是重新發明輪子。

例如,產品代碼可能看起來像:

// collection is a MongoCollection<T> object 
var items = collection.AsQueryable().Where(...linq expression...); 

和單元測試代碼(如果你有墊片,MS測試去):

using (ShimsContext.Create()) 
{     
    ShimLinqExtensionMethods.AsQueryableOf1MongoCollectionOfM0(
     (MongoCollection<T> x) => Fake_DB_Collection.AsQueryable()); 
    // After this, the above "collection.AsQueryable()" will be mocked as 
    // an in-memory collection, which can be any subclass of IEnumerable<T>    
}