C# 当从匿名函数调用.Is…()时,为什么Moq设置/验证匹配器失败
当我试图简化创建一个相当复杂的表达式树来设置/验证与moq的匹配时,我遇到了一些奇怪的行为 假设我在模拟下面定义的简单接口C# 当从匿名函数调用.Is…()时,为什么Moq设置/验证匹配器失败,c#,moq,C#,Moq,当我试图简化创建一个相当复杂的表达式树来设置/验证与moq的匹配时,我遇到了一些奇怪的行为 假设我在模拟下面定义的简单接口 public interface IService { int Send(int value); } 下面的代码表示5个测试。对每个mockSender.Setup(…)进行一次测试。有人能解释为什么标记为失败的测试会失败吗 [Test] public void TestInlineSetup() { const int expected = 5;
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>();
}
[测试]
public void TestInlineSetup()
{
预期常数int=5;
var mockSender=new Mock(MockBehavior.Loose);
//通行证
mockSender.Setup(s=>s.Send(It.IsAny())。返回(预期);
//失败
var sendMatch=It.IsAny();
mockSender.Setup(s=>s.Send(sendMatch))。返回(预期);
//通行证
mockSender.Setup(s=>s.Send(SendMatchFromMethod())。返回(预期);
//失败
var sendMatch=sendmatchfromthod();
mockSender.Setup(s=>s.Send(sendMatch))。返回(预期);
//失败(这有点做作,但我有理由想讨好它)
mockSender.Setup(s=>s.Send(SendMatchFromCurriedMethod())。返回(预期);
Assert.That(mockSender.Object.Send(预期),Is.EqualTo(预期));
}
公共静态int SendMatchFromMethod()
{
返回它。IsAny();
}
公共静态函数SendMatchFromCurriedMethod()
{
return()=>It.IsAny();
}
编辑:我知道Mock.Of(..),通常更喜欢使用它,但在这种情况下,它不是一个选项。这似乎与我不久前遇到的情况非常相似: 问题似乎在于何时对
It.IsAny()
进行评估。通过了两个测试后,将在设置(…)
中对其进行评估,效果良好。在前两个失败的测试中,它的评估超出了设置(…)
的范围,因此无法正确评估。变量中可能存储的是It.IsAny()
,这将是int
(0
)的默认值
我不知道上次测试失败的确切原因,但可能是因为作为一种优化,您的静态
Func
在Setup(…)
执行之前得到评估,也可能是在Setup(…)
之后得到评估,但无论如何,它都是在Setup(…)之外发生的
问题源于Moq试图解析提供的表达式树以创建参数匹配器的方式。您可以在此处找到来源:-
关于来源:-
匹配器是通过编译和执行作为参数传递的表达式并查找任何匹配项来检测的(请参阅)It.IsAny
- 上述步骤仅对方法调用和成员访问发生
It.IsAny
方法已在matcher工厂外评估。因此,您有一个0的MemberAccess表达式SendMatchFromMethod
被视为一个方法调用表达式,并且调用在MatcherFactory内进行计算It。Is
最后,
Match.Create
或MatchAttribute
可用于处理复杂的谓词,也许它们可能适合您的用例?正确,您不能使用它。i设置或验证的lambda表达式的任何外部