2012-07-13 49 views
1

我有一個數據庫,儲存庫類:如何模擬codefirst策略創建的EntityFramework數據庫?

public class DatabaseRepository : IRepository 
    { 
     private readonly Database _database; 

     public DatabaseRepository(Database database) 
     { 
      _database = database; 
     } 

     ... 

     public void Delete<TObject>(TObject entity) where TObject : BaseEntity 
     { 
      var dbSet = DbSet<TObject>(); 
      dbSet.Remove(entity); 
      Save(); 
     } 

     ... 

     private void Save() 
     { 
      try 
      { 
       _database.SaveChanges(); 
      } 
      catch(DbEntityValidationException dbEx) 
      { 
       // do some action 
      } 
     }  
    } 

我需要試塊的方法private void Save()catch,所以我需要的東西像...

[TestMethod] 
public void SaveShouldDoSomethingIfDabaBaseConnectFalls() 
{ 
    Mock<Database> mockDb = new Mock<Database>(); 
    mockDb.Setup(db => db.SaveChange()).Throws(new DbEntityValidationException()); 

    IRepository repository = new DatabaseRepository(mockDb.Object); 

    ... 
} 

所以我的問題是我怎麼能嘲笑實體框架數據庫? Mock<Database> mockDb = new Mock<Database>(); - 如何正確寫入?對於嘲笑我使用Moq

回答

3
  1. 定義IDatabase界面爲你DbContext與集爲代表的IIDbSet<T>屬性
  2. 實施FakeDbSet<T>: IDbSet<T>
  3. 更新Repository使用IDatabase代替Database

之後,你可以建造的IDatabase模擬。

http://refactorthis.wordpress.com/2011/05/31/mock-faking-dbcontext-in-entity-framework-4-1-with-a-generic-repository/

隨着這樣做,記得Implemeted一個打擊假冒分貝一套單元測試並不能保證你的代碼將工作對真正的數據庫。

LINQ-to-Entities(real DbSet)不支持LINQ-to-Objects(FakeDbSet)所具有的許多功能。因此,當您使用數據庫時,您的代碼可能會在執行時失敗。

此限制不會使單元測試對僞造的DbSet無效。測試仍然可以測試存儲庫中實施的業務規則。但是,您需要針對實際數據庫LINQ-to-Entities數據庫提供程序運行每個更新的linq語句(手動或從集成測試),以確保提供程序支持它。

有關於此「聖戰」主題的更多信息在這裏 - Fake DbContext of Entity Framework 4.1 to Test