我用实体框架[DB]开发了一个MVC应用程序。我没有使用Repository ORM,直接在实体上处理CRUD操作。MVC应用程序单元测试的模拟实体框架
现在我计划编写单元测试。
是否可以在不使用生产数据库的情况下模拟实体?
请建议最好的方式来模拟实体
我用实体框架[DB]开发了一个MVC应用程序。我没有使用Repository ORM,直接在实体上处理CRUD操作。MVC应用程序单元测试的模拟实体框架
现在我计划编写单元测试。
是否可以在不使用生产数据库的情况下模拟实体?
请建议最好的方式来模拟实体
一种可能的方式是包装在一个界面中的现有实体框架类。因此,例如,您可以创建一个名为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
返回的实际对象。
我在这个主题上撰写的这篇博文可能会让你感兴趣:http://www.vannevel.net/2015/02/26/11/它使用Effort简单地创建一个内存数据库,其他所有工作都只是工作一样。 – 2015-03-13 12:30:41