![](/img/trans.png)
[英]Why use It.is<> or It.IsAny<> if I could just define a variable?
[英]How can I use It.IsAny as a parameter?
我有一个测试类调用MyClass
的模拟,我之前Setup
了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>())
- 我的测试没有通过,但是如果我直接使用它调用Verify方法,它将起作用.IsAny:
_myClassMock.Verify(ic => ic.DoStuffA(It.IsAny<int>()), Times.Once());
_myClassMock.Verify(ic => ic.DoStuffB(It.IsAny<int>()), Times.Once());
我从这个问题的答案中理解,Moq处理It.IsAny在表达式中指定为Setup / Verify时,是否有任何解决方法?
这不起作用的原因:
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
示例以接受多个表达式。 这将允许您在DoStuffB
上验证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在评论中建议的那样。
It.IsAny
只允许Moq匹配方法调用的未来调用(如果在Setup
构造中使用),如果您的Setup
未设置It.IsAny
则无法使用Verify
或Assert
执行此操作。 因为It.IsAny
总是返回输入的默认值。
因此,如果您想在Verify
使用It.IsAny
,您应首先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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.