我正在编写一个模拟DbContext的IDbSet
属性的单元测试;但是,我似乎得到了一些奇怪的结果。
这是我模拟数据的代码:
var myData1 = new List<MyData1>()
{
new MyData1() { Id = 2, Test = "test" },
new MyData1() { Id = 3, Test = "test" },
new MyData1() { Id = 4, Test = "test" }
}.AsQueryable();
IDbSet<MyData1> myDbSet = Substitute.For<IDbSet<MyData1>>();
myDbSet.Provider.Returns(myData1.Provider);
myDbSet.Expression.Returns(myData1.Expression);
myDbSet.ElementType.Returns(myData1.ElementType);
myDbSet.GetEnumerator().Returns(myData1.GetEnumerator());
myDbContext.MyData1.Returns(myDbSet);
. . .
myDbContext.MyData2.Returns(myDbSet2);
. . .
myDbContext.MyData3.Returns(myDbSet3);
当我询问数据时;例如:
using (IMyDbContext myDbContext = _dbContextGenerator.GenerateDbContext())
{
var myData = myDbContext.MyData1.ToList();
}
_dbContextGenerator
仅被替换为返回测试DbContext,而不是真正的DbContext:
IDbContextGenerator dbContextGenerator = Substitute.For<IDbContextGenerator>();
dbContextGenerator.GenerateDbContext().Returns(myDbContext);
这似乎有效;但是,如果我两次调用该方法;没有。所以:
using (IMyDbContext myDbContext = _dbContextGenerator.GenerateDbContext())
{
myData = myDbContext.MyData1.ToList();
}
Assert.Equal(3, myData.Count());
作品;但是:
using (IMyDbContext myDbContext = _dbContextGenerator.GenerateDbContext())
{
myData = myDbContext.MyData1.ToList();
}
using (IMyDbContext myDbContext = _dbContextGenerator.GenerateDbContext())
{
myData = myDbContext.MyData1.ToList();
}
Assert.Equal(3, myData.Count());
不是。我没有返回任何数据;但是,如果我调试该行,则可以看到:
myDbContextMyData1.Provider
包含正确的测试数据。
请有人为此指出正确的方向吗?
答案 0 :(得分:1)
问题是
myDbSet.GetEnumerator().Returns(myData1.GetEnumerator());
每次调用时都会返回相同的枚举器实例。
并且由于枚举数仅是正向的,因此需要将其重置。多次调用而不重置将表现出所描述的行为,因为指针位于末尾,因此只能枚举一次。
使用委托回调,以便在每次调用模拟程序时都调用它,以在每次调用GetEnumerator()
时返回一个新的枚举数。
myDbSet.GetEnumerator().Returns(_ => myData1.GetEnumerator());
现在多次枚举模拟对象应表现出预期的效果。