[英]Moq throwing NullReferenceException on Verify with It.Is but not It.IsAny
[英]Why does Moq setup/verify matcher fail when It.Is…() is called from anonymous function
当尝试简化为与Moq匹配的Setup / Verify匹配创建相当复杂的表达式树时,我遇到了一些奇怪的行为。
假设我在嘲笑下面定义的简单接口
public interface IService
{
int Send(int value);
}
以下代码表示5个测试。 每个mockSender.Setup(...)
一个测试。 任何人都可以解释为什么标记为失败的测试失败了吗?
[Test]
public void TestInlineSetup()
{
const int expected = 5;
var mockSender = new Mock<IService>(MockBehavior.Loose);
//passes
mockSender.Setup(s => s.Send(It.IsAny<int>())).Returns(expected);
//fails
var sendMatch = It.IsAny<int>();
mockSender.Setup(s => s.Send(sendMatch)).Returns(expected);
//passes
mockSender.Setup(s => s.Send(SendMatchFromMethod())).Returns(expected);
//fails
var sendMatch = SendMatchFromMethod();
mockSender.Setup(s => s.Send(sendMatch)).Returns(expected);
//fails (this is somewhat contrived, but I have reasons for wanting to curry this)
mockSender.Setup(s => s.Send(SendMatchFromCurriedMethod()())).Returns(expected);
Assert.That(mockSender.Object.Send(expected), Is.EqualTo(expected));
}
public static int SendMatchFromMethod()
{
return It.IsAny<int>();
}
public static Func<int> SendMatchFromCurriedMethod()
{
return () => It.IsAny<int>();
}
编辑:我知道Mock.Of <..>(..)并且通常更喜欢使用它但在这种情况下它不是一个选项。
问题源于Moq尝试解析提供的表达式树以创建参数匹配器的方式。 你可以在这里找到来源: -
http://code.google.com/p/moq/source/browse/trunk/Source/MatcherFactory.cs
参考来源: -
It.IsAny<int>
匹配器(请参阅此处 )。 所以考虑到这一点....
It.IsAny<int>
方法。 因此,您将MemberAccess表达式设置为0。 SendMatchFromMethod
被视为方法调用表达式,并且在MatcherFactory中计算调用。 It.Is<Any>
说实话,第四个测试应该通过,它似乎是一个疏忽,它可能只是因为它有点边缘情况。
最后, Match.Create<T>
或MatchAttribute
可用于处理复杂谓词,也许它们可能适合您的用例?
这似乎与我前一段时间遇到的情况非常相似: 使用It.IsAny <DateTime>()的Moq单元测试失败
当It.IsAny<int>()
被评估时,问题似乎就出现了。 通过2次测试后,它将在Setup(...)
内部进行评估,该工作正常。 在前两个失败的测试中,它的评估超出了Setup(...)
的范围,因此无法正确评估。 可能存储在变量中的是It.IsAny<int>()
,它将是int
( 0
)的默认值。
我不知道上次测试失败的确切原因,但它可能是作为优化,您的静态Func<int>
在Setup(...)
执行之前得到评估,或者可能是它在之后得到评估Setup(...)
,但无论哪种方式都发生在Setup(...)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.