2012-07-13 47 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