我想通过将It.IsAny<IWhatever>
分配给局部变量来使我的单元测试代码稍微可读一些,但我的mock无法识别方法调用,这让我感到惊讶。
这适用于
rotationStrategyMock.
Setup(rotateStrategy => rotateStrategy.IsRotationRequired(It.IsAny<IProduct>(), null)).
Returns(true);
当我按如下方式重写它时(将It.IsAny
提取到本地var)
var anyProduct = It.IsAny<IProduct>();
rotationStrategyMock.
Setup(rotateStrategy => rotateStrategy.IsRotationRequired(anyProduct, null)).
Returns(true);
然后mock返回false,因为方法调用无法识别。
有人能解释为什么第二种选择不起作用吗?
Setup
方法接受一个Expression
,它基本上是一个未编译的Func
。这里的关键是"未编译"
当您将It.IsAny<T>()
直接传递到Setup方法中时,它生成的对象在运行时之前保持未编译状态。然而,通过首先将其实例化为一个单独的步骤,传递到Setup
中的对象就是一个具体的实例。现在,没有一个任意的Product
能通过测试,只有那个具体的东西。您可以在以下代码中看到这一点:
public interface ITest
{
bool IsTrue(int i);
}
public static TestClass
{
public static void Main()
{
var isAny = It.IsAny<int>();
var tester = new Mock<ITest>();
tester.Setup(t => t.IsTrue(isAny)).Returns(true);
Console.WriteLine(tester.Object.IsTrue(1)); //false
Console.WriteLine(tester.Object.IsTrue(isAny)); //true
}
}
这里还有一个更深入的答案