2013-02-05 53 views
1

我一直在寻找各种方法来实现与EF的存储库模式,特别是使用通用存储库。测试假存储库

我一直在尝试使用具有IContext属性的IRepository,因此IRepository的任何实现之间的唯一区别就是上下文。我发现这非常困难,我已经放弃了“假语境”的方针,现在已经只是名单的字典作为假库我的“上下文”:

public Dictionary<Type, object> _sets = new Dictionary<Type, object>(); 

并对其进行操作,将就在假像这样:

public void Add<T>(T entity) where T : class 
    { 
     var set = _sets[typeof (T)] as IQueryable<T>; 
     var updatedSet = set.ToList(); 
     updatedSet.Add(entity); 
     _sets[typeof (T)] = updatedSet.AsQueryable<T>(); 
    } 

在真实的版本库,我可以只使用:

void Add<T>(T entity) 
    { 
     Set<T>().Add(entity); 
    } 

在我更新的方法,我就必须有类似的不同的实现方式,以适应一个真正的上下文继承DbContext,以及一个使用基于集合的方法的伪造。

这种方法让我很紧张。正如其他人在其他问题中提到的那样,现在我的存储库实现如此不同,以至于我认为只有在虚拟和真实存储库都运行之前,我才能相信测试。

我只是一个小孩,这是超过这个?或者是否有更好的方法来实现更像DbContext的假上下文,所以我不必具有实现存储库接口的完全不同的类?

总结:我了解使用内存存储库进行测试的优点。我的问题是,当我不得不做两个不同的存储库实现时,这是否意味着我做错了什么,或者这只是用假货测试的代价,如果逻辑测试通过,我不应该'那么多汗?

回答

0

下面是我们在我正在开发的项目中所做的工作:我们有一个围绕EF的存储库包装类,以便我们可以在需要时使用模块进行单元测试。我认为你在做一个内存资料库,但是我最终决定不这样做,因为我只是真的需要它来查询。但是,由于Linq To Entities是Linq to Objects的子集。单元测试可能会通过,但之后集成测试失败,因为您可能使用的功能不属于Linq to Entities的一部分。如果我需要集成测试该查询并且不能相信单元测试,那么执行这两个操作并不合适。

对于单元测试,我只是对存储库进行了模拟并验证了适当的方法(Insert或其他)已被调用。对于删除/插入/任何集成测试,只需点击实际的数据库。

对于实际的查询,我只做了集成测试。我将查询移到了一个单独的函数中。我的代码将调用该函数来检索查询结果,并且我可以将该函数与其中的查询分开进行集成测试,并且单元测试查询结果的处理。

我不知道这是否合理,或者有更好的方法去做,但这就是我最终做的。

另外,如果你想继续在内存中执行 我想你应该能够做到以下几点:

只要有对象的列表,并使用OfType返回正确的类型:

public TEntity Get<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> where, params System.Linq.Expressions.Expression<Func<TEntity, object>>[] includeProperties) where TEntity : class 
{ 
    return _repositories.OfType<TEntity>().AsQueryable().Where(where).FirstOrDefault(); 
} 

public TEntity Insert<TEntity>(TEntity tEntity) where TEntity : class 
{ 
    _repositories.Add(tEntity); 
    return tEntity; 
} 
+0

谢谢。我可能会嘲笑,但我试图在每一步都弄脏自己的手,所以现在我只是坚持使用虚假内存的方法,以及真实数据的EF上下文。 昨天我正在尝试你的方法,但它花了我几个失败的测试,以实现我无法添加到一个键入IQueryable的集合。您的评论确实让我意识到,我不需要添加一组IQueryable,但是。现在,我只是将该集添加为一个列表 - 使添加/更新/删除更清晰,并且我可以使用方法QuerySet 将列表返回为IQueryable,当我需要它在我的测试中进行查询时。 – monkeydeus