使用Moq模拟foreach循环

6

我想循环遍历XmlNodeList。如何在Moq中模拟一个XmlNodeList,以便您可以像在foreach循环中一样进行遍历:

        foreach (XmlNode xmlNode in nodes)
        {
            //Do something with node
        }

我曾试过通过SetupSequence方法进行设置,但是我无法创建所需的模拟。


1
你试图通过这个测试实现什么有点难以理解,但是你可能想考虑在这里进行集成测试而不是单元测试,提供你的 XML 的字符串表示形式并在真实数据上测试你的循环。 - nieve
你说得对,我确实处于那个灰色地带,在那里你可以讨论真正单元测试的价值。然而,在其他不那么灰色的领域,这可能会很有用。我难道不会在所有foreach循环中遇到同样的问题吗? - Morten
区别在于你正在循环的内容——XML文档比任何其他集合都更复杂,因此可能不是简单单元测试的最佳选择,这显然取决于你要测试什么。此外,这个问题可能是让你重新思考设计的好指标?只是一个想法。 - nieve
@nieve 谢谢你对Moq的能力进行了澄清,这对我来说完全是新闻。更有帮助的是,foreach是否会隐式调用被foreach的对象的GetEnumerator方法?也许模拟该方法可以帮你找到你想要的结果。 - tmesser
模拟某个东西的整个想法是为了节省我们的时间,更重要的是“解耦”我们的测试与其他依赖关系。在这种情况下,即使我们没有整个代码(因此很难说),似乎您最终仍然会通过“设置”模拟对象或设置真实对象来完成确切的工作,因此我的建议是如此。 - nieve
1个回答

10

foreach 在幕后调用 GetEnumerator ,这就是您需要模拟的内容:

var xmlNodesMock = new Mock<XmlNodeList>();
xmlNodesList
    .Setup(l => l.GetEnumerator())
    .Returns(new XmlNode[] { /* values go here */ }.GetEnumerator());

自然地,您需要在Returns方法中使用实际值初始化XmlNode数组。请记住,模拟的列表必须可注入到被测试的方法中,以便您可以替换实际实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接