gpt4 book ai didi

c# - 枚举 Moq'ed IDbSet 引发异常 : "Collection was modified; enumeration operation may not execute."

转载 作者:行者123 更新时间:2023-11-30 23:12:38 25 4
gpt4 key购买 nike

我正在尝试使用 Moq 框架模拟 IDbSet。单元测试应向现有模拟 DbSet 集合 (SetUp) 添加新记录(实体)并返回新集合的计数。

我的 TestInitialize 设置如下所示:

public class BlogTests
{
private IRepository _repository;

[TestInitialize]
public void Setup()
{
var blogEntries = new List<BlogEntry>
{
new BlogEntry()
{
//...init the object
}
};
var queryableBlogEntries = QueryableDbSetMock.GetQueryableMockDbSet<BlogEntry>(blogEntries);
var repoMock = new Mock<IRepository>();
repoMock.Setup(x => x.BlogEntries).Returns(queryableBlogEntries);
_repository = repoMock.Object;
}

这里是返回模拟 IDbSet 的方法,给定一个列表:

public class QueryableDbSetMock
{
public static IDbSet<T> GetQueryableMockDbSet<T>(List<T> sourceList) where T : class
{
var queryable = sourceList.AsQueryable();

var dbSet = new Mock<IDbSet<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;
}
}

在单元测试中,我会安排一个新的 BlogEntry 对象并尝试将其添加到模拟的 IDbSet,之后我希望集合的总数为两个元素/记录。

以下单元测试成功:

public void IndexTest()
{
//Arrange
var entries = _repository.BlogEntries;

var newEntry = new BlogEntry()
{
//...init the second object
};

//Act
entries.Add(newEntry);
var count = entries.Count();

//Assert
Assert.AreEqual(2, count);
}

但是当我尝试使用 GetEnumerator 方法进行计数时,Enumerator.MoveNext 命令将抛出异常:

'System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.' '.

这里是修改后的单元测试代码:

[TestMethod()]
public void IndexTest2()
{
//Arrange
var entries = _repository.BlogEntries;

var newEntry = new BlogEntry()
{
//...init the second object
};

//Act
entries.Add(newEntry);
var enumerator = entries.GetEnumerator();
int count = 0;
while (enumerator.MoveNext()) //Throws Exception
{
count++;
}
//Assert
Assert.AreEqual(2, count);
}

所以我的困惑在于第一个单元测试似乎在计算更改集合的计数方面没有问题,但是当尝试以困难的方式进行计数时,测试失败了。

如有任何澄清,我们将不胜感激!

最佳答案

由于最小起订量的设置方式,迭代器不会重置,因为所有调用都使用同一个实例

.Returns(queryable.GetEnumerator());

每次都返回相同的枚举器实例,使用一次需要重置(修改集合后导致异常)。

如果你想在每次调用时都有一个新的枚举器,那么你需要传递 Returns 一个 lambda 表达式:

GetEnumerator 方法的设置更新为

.Returns(() => queryable.GetEnumerator()); //<-- note the function

每次调用 GetEnumerator() 时都会调用 lambda。所以现在多次枚举模拟应该会按预期工作。

这将允许在枚举器上进行多次传递,因为初始设置将为每次调用返回相同的枚举器。由于之前未重置枚举器,因此当您尝试再次遍历它时遇到了错误。

关于c# - 枚举 Moq'ed IDbSet 引发异常 : "Collection was modified; enumeration operation may not execute.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43995330/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com