我有一个调用MyClass模拟的测试类,之前我已经同时调用了DoStuffA和DoStuffB。
我尝试在一个方法中封装几个Verify调用,如下所示:
void VerifyMany(int input)
{
_myClassMock.Verify(ic => ic.DoStuffA(input), Times.Once());
_myClassMock.Verify(ic => ic.DoStuffB(input), Times.Once());
}如果我用It.IsAny<int>()作为输入来调用我的方法-- VerifyMany(It.IsAny<int>()) --我的测试没有通过,但是如果我直接用It.IsAny调用验证方法,它就会工作:
_myClassMock.Verify(ic => ic.DoStuffA(It.IsAny<int>()), Times.Once());
_myClassMock.Verify(ic => ic.DoStuffB(It.IsAny<int>()), Times.Once());我从这问题的答案中了解到,当指定用于设置/验证时,Moq在表达式中对It.IsAny的处理方式不同,有什么解决办法吗?
发布于 2019-02-14 08:38:20
这不起作用的原因是:
void VerifyMany(int input)
{
_myClassMock.Verify(ic => ic.DoStuffA(input), Times.Once());
_myClassMock.Verify(ic => ic.DoStuffB(input), Times.Once());
}是因为It.IsAny<int>() (简单地调用)返回0。因此,从本质上说,当用VerifyMany调用It.IsAny<int>()时,您将0传递给VerifyMany。这反过来意味着DoStuffA(0)和DoStuffB(0)将被验证(而不是您可能想要的任何整数值)。
另一种调用:
_myClassMock.Verify(ic => ic.DoStuffA(It.IsAny<int>()), Times.Once());
_myClassMock.Verify(ic => ic.DoStuffB(It.IsAny<int>()), Times.Once());会工作,因为ic => ic.DoStuffA(It.IsAny<int>()部件从未直接调用过。它被转换成表达式树,而Moq只遍历(或者访问)该表达式树。这意味着它将在表达式树中找到It.IsAny<int>(),然后能够用任何整数值验证对DoStuffA的调用(它也在同一表达式树中找到该调用)。(有关表达式树的更多信息,请访问阅读这篇文章)
您可以通过创建一个将对Verify的调用抽象出来并接受如下表达式的方法来使其半工作:
void VerifyOnce(Expression<Action<ClassMockIsBasedOn>> callToVerify)
{
_myClassMock.Verify(callToVerify, Times.Once());
}这样你就可以这样称呼:
VerifyOnce(ic => ic.DoStuffA(It.IsAny<int>())还可以扩展VerifyOnce示例以接受多个表达式。这将允许您在一行中验证DoStuffA和DoStuffB:
void VerifyOnce(params Expression<Action<ClassMockIsBasedOn>>[] callsToVerify)
{
foreach(var callToVerify in callsToVerify)
{
_myClassMock.Verify(callToVerify, Times.Once());
}
}这样就可以打电话了:
VerifyOnce(ic => ic.DoStuffA(It.IsAny<int>(),
ic => ic.DoStuffB(It.IsAny<int>());当然,您可以用泛型替换ClassMockIsBasedOn。并添加重载,该重载允许返回值(而不是无效)或接受多个参数的方法,如Brett在注释中所建议的那样。
发布于 2019-02-14 08:21:38
It.IsAny只允许Moq匹配将来调用方法的调用(如果在Setup构造中使用),如果您的Setup尚未设置It.IsAny,则不能使用Verify或Assert进行调用。因为It.IsAny总是返回输入的默认值。
因此,如果您想在It.IsAny at Verify上使用Setup,那么首先应该为Setup方法设置目标:
校正
_myClassMock.Setup(ic => ic.DoStuffA(It.IsAny<int>())).Returns(// Something here);
_myClassMock.Verify(ic => ic.DoStuffA(It.IsAny<int>()), Times.Once());错误
_myClassMock.Setup(ic => ic.DoStuffA(1)).Returns(// Something here);
_myClassMock.Verify(ic => ic.DoStuffA(It.IsAny<int>()), Times.Once());https://stackoverflow.com/questions/54685818
复制相似问题