2013-02-05 77 views
1

我一直在尋找各種方法來實現與EF的存儲庫模式,特別是使用通用存儲庫。測試假存儲庫

我一直在嘗試使用具有IContext屬性的IRepository,因此IRepository的任何實現之間的唯一區別就是上下文。我發現這非常困難,我已經放棄了「假語境」的方針,現在已經只是名單的字典作爲假庫我的「上下文」:

public Dictionary<Type, object> _sets = new Dictionary<Type, object>(); 

並對其進行操作,將就在假像這樣:

public void Add<T>(T entity) where T : class 
    { 
     var set = _sets[typeof (T)] as IQueryable<T>; 
     var updatedSet = set.ToList(); 
     updatedSet.Add(entity); 
     _sets[typeof (T)] = updatedSet.AsQueryable<T>(); 
    } 

在真實的版本庫,我可以只使用:

void Add<T>(T entity) 
    { 
     Set<T>().Add(entity); 
    } 

在我更新的方法,我就必須有類似的不同的實現方式,以適應一個真正的上下文繼承DbContext,以及一個使用基於集合的方法的僞造。

這種方法讓我很緊張。正如其他人在其他問題中提到的那樣,現在我的存儲庫實現如此不同,以至於我認爲只有在虛擬和真實存儲庫都運行之前,我才能相信測試。

我只是一個小孩,這是超過這個?或者是否有更好的方法來實現更像DbContext的假上下文,所以我不必具有實現存儲庫接口的完全不同的類?

總結:我瞭解使用內存存儲庫進行測試的優點。我的問題是,當我不得不做兩個不同的存儲庫實現時,這是否意味着我做錯了什麼,或者這只是用假貨測試的代價,如果邏輯測試通過,我不應該'那麼多汗?

回答

0

下面是我們在我正在開發的項目中所做的工作:我們有一個圍繞EF的存儲庫包裝類,以便我們可以在需要時使用模塊進行單元測試。我認爲你在做一個內存資料庫,但是我最終決定不這樣做,因爲我只是真的需要它來查詢。但是,由於Linq To Entities是Linq to Objects的子集。單元測試可能會通過,但之後集成測試失敗,因爲您可能使用的功能不屬於Linq to Entities的一部分。如果我需要集成測試該查詢並且不能相信單元測試,那麼執行這兩個操作並不合適。

對於單元測試,我只是對存儲庫進行了模擬並驗證了適當的方法(Insert或其他)已被調用。對於刪除/插入/任何集成測試,只需點擊實際的數據庫。

對於實際的查詢,我只做了集成測試。我將查詢移到了一個單獨的函數中。我的代碼將調用該函數來檢索查詢結果,並且我可以將該函數與其中的查詢分開進行集成測試,並且單元測試查詢結果的處理。

我不知道這是否合理,或者有更好的方法去做,但這就是我最終做的。

另外,如果你想繼續在內存中執行 我想你應該能夠做到以下幾點:

只要有對象的列表,並使用OfType返回正確的類型:

public TEntity Get<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> where, params System.Linq.Expressions.Expression<Func<TEntity, object>>[] includeProperties) where TEntity : class 
{ 
    return _repositories.OfType<TEntity>().AsQueryable().Where(where).FirstOrDefault(); 
} 

public TEntity Insert<TEntity>(TEntity tEntity) where TEntity : class 
{ 
    _repositories.Add(tEntity); 
    return tEntity; 
} 
+0

謝謝。我可能會嘲笑,但我試圖在每一步都弄髒自己的手,所以現在我只是堅持使用虛假內存的方法,以及真實數據的EF上下文。 昨天我正在嘗試你的方法,但它花了我幾個失敗的測試,以實現我無法添加到一個鍵入IQueryable的集合。您的評論確實讓我意識到,我不需要添加一組IQueryable,但是。現在,我只是將該集添加爲一個列表 - 使添加/更新/刪除更清晰,並且我可以使用方法QuerySet 將列表返回爲IQueryable,當我需要它在我的測試中進行查詢時。 – monkeydeus