如何解决模拟验证DbSet失败,并且未验证GetEnumerator
我正在尝试使用最小订量(moq)模拟我们的数据库。 这里的问题是,EntityFramework中的某些方法返回DbSet对象,这些对象在我的代码中使用foreach进行了迭代。
现在我致电VerifyNoOtherCalls();在定义的测试方法的末尾。但是这里的测试使我大吃一惊,因为foreach循环从IEnumerable接口调用了GetEnumerator(),我没有验证。但这是不可能的,因为DbSet本身不实现GetEnumerator(),并且moq不允许在Lambda中调用ToList()。
现在我有两个问题:
- DbSet如何实现IEnumerable接口,而不直接或在基类中实现GetEnumerator方法?
- 如何运行测试?我已经在互联网上找到了一些说明,所以我决定自己模拟DbSet:
public static DbSet<T> GetQueryableMockDbSet<T>(List<T> sourceList) where T : class
{
var queryable = sourceList.AsQueryable();
var dbSet = new Mock<DbSet<T>>();
dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>((s) => sourceList.Add(s));
return dbSet.Object;
}
但是,这也不起作用。
解决方法
第一个问题,DbSet<>
has an explicit implementation for IQueryable.GetEnumerator()
。这样就可以将DbSet用作IEnumerable<>
,而不会造成混乱的智能感知,并且通常不会直接在DbSet上调用这些方法。
我不太肯定为什么您发布的代码无法正常工作,但是您可以尝试在GetEnumerator()
上模拟dbSet.AsIEnumerable<T>()
。
不过,在更高的层次上,我发现在嘲笑 DbSet中没有什么价值(像 service 一样对待它,您需要模拟和验证其方法) 。我将重点放在伪造上(将其像一个集合一样处理,可以指定其内容)。因此,根据我的经验,致电VerifyNoOtherCalls()
可能无济于事。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。