2015-03-13 136 views
1

我用實體框架[DB]開發了一個MVC應用程序。我沒有使用Repository ORM,直接在實體上處理CRUD操作。MVC應用程序單元測試的模擬實體框架

現在我計劃編寫單元測試。

是否可以在不使用生產數據庫的情況下模擬實體?

請建議最好的方式來模擬實體

+0

我在這個主題上撰寫的這篇博文可能會讓你感興趣:http://www.vannevel.net/2015/02/26/11/它使用Effort簡單地創建一個內存數據庫,其他所有工作都只是工作一樣。 – 2015-03-13 12:30:41

回答

3

一種可能的方式是包裝在一個界面中的現有實體框架類。因此,例如,您可以創建一個名爲IDbContextAdapter的接口並實施一個名爲DbContextAdapter的類。然後這將實現接口,並簡單地將呼叫轉接到真實的DbContext上。

public interface IDbContextAdapter 
{ 
    IEnumerable<DbEntityValidationResult> GetValidationErrors(); 
    int SaveChanges();  
    ... 
} 

那麼類...

public class DbContextAdapter : IDbContextAdapter 
{ 
    private readonly DbContext _realContext; 

    public DbContextAdapter(DbContext context) 
    { 
     _realContext = context; 
    } 

    public IEnumerable<DbEntityValidationResult> GetValidationErrors() 
    { 
     return _realContext.GetValidationErrors(); 
    } 

    public int SaveChanges() 
    { 
     _realContext.SaveChanges(); 
    } 
} 

現在你可以使用IDbContextAdapter整個代碼,你可以在測試過程中嘲笑接口。您可以爲每個使用外部調用的實體框架類執行此操作,並且還可以在您使用DbContext方法時添加額外的錯誤檢查等。

我對Azure Table/Queue Storage使用了這種方法,它運行良好,但需要額外的編碼才能包裝真實的對象。

更新#1:作爲旁註,我不會包裝所有的EF對象。相反,只是那些訪問外部資源的人。所以如果我的方法有一個參數是一個EF類型的對象,並且這個對象只有一些屬性,那麼將它包含在你的方法簽名中,不要麻煩包裝它(這也適用於返回值)。

更新#2:更新代碼示例以說明UPDATE#1中的點。請注意0​​方法如何不打擾包裝EF類型DbEntityValidationResult,而是簡單地返回從實際DbContext返回的實際對象。