当尝试简化为与Moq匹配的Setup/Verify匹配创建相当复杂的表达式树时,我遇到了一些奇怪的行为.
假设我在嘲笑下面定义的简单接口
public interface IService
{
int Send(int value);
}
Run Code Online (Sandbox Code Playgroud)
以下代码表示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>();
}
Run Code Online (Sandbox Code Playgroud)
编辑:我知道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可以用来处理复杂的谓词,也许它们可能适合你的用例?
| 归档时间: |
|
| 查看次数: |
1773 次 |
| 最近记录: |