我在测试中设置我的一个模拟时遇到了一些问题,最终会多次调用设置但参数不同所以:
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/