2015-03-13 133 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返回的实际对象。