结果视图未在 VS 调试器中正确枚举

Result view not enumerating correctly in VS Debugger

如果我模拟一个集合让 Moq 实现 GetEnumerator 回调 GetEnumerator一个不同的集合,如果我调用 MoveNext/Current 和 foreach.

我会得到正确的结果

当我尝试使用 Visual Studio 调试器的 结果视图 时,我得到 "Enumeration yielded no results"。是否有一个原因?不就是枚举缓存吗?

var dbParameterMock1 = CreateDbParameterMock("@Parameter1", 1);

var dbParameters = new ArrayList { dbParameterMock1.Object };

var dbParameterCollectionMock = new Mock<DbParameterCollection>();

dbParameterCollectionMock.Setup(collection => collection.GetEnumerator()).Returns(dbParameters.GetEnumerator());

return dbParameterCollectionMock;

这肯定与调试器与对象交互的方式有关。我在控制台应用程序中重新创建了您的示例,但添加了一个回调,因此每次调用 GetEnumerator 时我都会知道:

var dbParameterMock1 = new Mock<DbParameter>().SetupAllProperties();
dbParameterMock1.Object.ParameterName = "@Parameter1";
dbParameterMock1.Object.Value = 1;

var dbParameters = new ArrayList { dbParameterMock1.Object };
var dbParameterCollectionMock = new Mock<DbParameterCollection>();
dbParameterCollectionMock.Setup(collection => collection.GetEnumerator())
    .Returns(dbParameters.GetEnumerator())
    .Callback(() => Console.WriteLine("GetEnumeratorCalled"));

foreach (DbParameter p in dbParameterCollectionMock.Object)
{
    Console.WriteLine(p.ParameterName);
}

如果我在 foreach、运行 代码上设置断点,然后使用调试器查看 dbParameterCollectionMock.Object,我会看到 GetEnumerator() 被调用了两次。第一个将 return ArrayList 的实际枚举器,而后续调用将 return null。似乎调试器正在枚举第二个调用,因此 "Enumeration yielded no results" 消息。

因此,在上面的情况下,调试器已经调用了 GetEnumerator 的一个模拟调用,如果我继续 运行 应用程序,则 foreach 会在不执行任何操作的情况下完成。同样,因为调试器已经调用了一个,模拟的 GetEnumerator.

不真实 "answer" 但可能有助于阐明您所看到的内容。

感谢@Patrick Steele 帮助我意识到我的错误:

问题在这里:

[...].Returns(dbParameters.GetEnumerator());

正在获取枚举器实例并将其用于模拟。第一次使用后,它可能会被丢弃并以某种方式设置为 null。

如建议的那样,结果视图正在枚举两次并显示第二次为空的结果(和一个问号,因为显然处置的枚举器有问题)。

为了在随后的枚举中存活下来,它需要每次使用 lambda 来查询一个新的模拟:

[...].Returns(() => dbParameters.GetEnumerator());