繁体   English   中英

我如何使用It.IsAny作为参数?

[英]How can I use It.IsAny as a parameter?

我有一个测试类调用MyClass的模拟,我之前SetupDoStuffADoStuffB

我试图在一个方法中包装几个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上验证DoStuffADoStuffB

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则无法使用VerifyAssert执行此操作。 因为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM