c# - Moq - 如何在循环中调用具有不同参数的相同设置

标签 c# testing moq

我在测试中设置我的一个模拟时遇到了一些问题,最终会多次调用设置但参数不同所以:

var testMock = new Mock<SomeClass>(MockBehavior.Strict);

for (int i = 30000; i <= 300000; i+=10000)
{
   testMock.Setup(x => x.MethodA(SomeStaticClass.GetIt(varA, varB, i), It.IsAny<int>()))
       .Returns(new List<SomeClass>());
}

所以,上面的方法是行不通的。似乎只有最后一次迭代才会被模拟“记住”。我如何才能像上面打算的那样在一个模拟上设置多个设置?

最佳答案

当您从 lambda 表达式内部使用外部变量时 - 它会被此 lambda 表达式“捕获”并延长其生命周期。在此示例中,lambda 表达式是您传递给 Setup 调用的内容,外部变量是 i 循环变量。它的生命周期应该在 for 循环之外延长,因为您不知道 Setup 将如何处理该变量 - 它可能会在 之后长时间使用它>for 循环甚至封装函数结束。所以编译器用编译器生成的类中的字段替换这个局部变量。现在,您在循环中传递给 Setup 的所有 lambda 都引用完全相同的位置 - 编译器生成的类的字段,i 变量被替换。

当您调用模拟函数时 - Moq 会将您传递的参数与可用设置进行比较。但是由于所有设置都引用相同的位置 - 它们都引用 i 的最后一个值,它在循环结束时具有。

将循环变量复制到另一个变量时:

for (int i = 30000; i <= 300000; i+=10000)
{
   var tmp = i;
   testMock.Setup(x => x.MethodA(SomeStaticClass.GetIt(varA, varB, tmp), It.IsAny<int>()))
       .Returns(new List<SomeClass>());
}

它也被捕获并延长了它的生命周期,但是这次每个循环迭代都有它自己的变量,所以它是编译器生成类的自己的实例,现在所有 Setup lambda 使用不同的值。

关于c# - Moq - 如何在循环中调用具有不同参数的相同设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48762740/

相关文章:

c# - 如何在 C# nunit 中断言字典?

c# - 无法以编程方式覆盖 IIS 虚拟目录/应用程序中的文件(文件始终被锁定)

c# - Checked 和 Unchecked 运算符似乎在以下情况下不起作用

c# - 如何在查询 LINQ 中表达 IN(参数列表)?

actionscript-3 - 我正在尝试测试文本输入框是否具有焦点

javascript - 有什么方法可以打开 cypress 并只包含包含关键字的测试文件?例如。来自 domains-lifecycle.spec.jsx 的生命周期

c# - Moq 枚举在 FirstOrDefault 上消失

c# - 无法使用 WSDL 定义

ruby-on-rails - 如何干燥 Controller 测试

c# - 依赖于 Mocked 属性的属性