c# - 如何使用 It.IsAny 作为参数?

标签 c# moq

我有一个测试类调用 MyClass 的模拟, 我有 Setup两者 DoStuffADoStuffB以前。

我试过包装几个 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 调用 Verify 方法,它将起作用:

_myClassMock.Verify(ic => ic.DoStuffA(It.IsAny<int>()), Times.Once());
_myClassMock.Verify(ic => ic.DoStuffB(It.IsAny<int>()), Times.Once());

我从this的答案中了解到当指定给设置/验证时,最小起订量在表达式中以不同方式处理 It.IsAny 的问题,是否有任何解决方法?

最佳答案

这不起作用的原因:

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 的调用(它也在同一表达式树中找到)具有任何整数值。 (有关表达式树的更多信息,请随时 read this )

您可以通过创建一个方法来抽象对 Verify 的调用,从而使这个半工作完成。 away 并接受这样的表达式:

void VerifyOnce(Expression<Action<ClassMockIsBasedOn>> callToVerify)
{
    _myClassMock.Verify(callToVerify, Times.Once());
}

它允许你这样调用它:

VerifyOnce(ic => ic.DoStuffA(It.IsAny<int>())

您还可以扩展 VerifyOnce接受多个表达式的示例。这将允许您验证 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 在评论中所建议的那样。

关于c# - 如何使用 It.IsAny 作为参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54685818/

相关文章:

C# Moq 框架返回空引用不正确的对象

linq - Moq 测试 LINQ Where 查询

.net - 你能帮我理解起订量回调吗?

c# - 将字符串值与枚举的字符串值进行比较

c# - WebAPI 路由中的通配符参数不应该匹配

c# - 如何使用最小起订量来验证是否将类似的对象作为参数传入?

c# - 为什么 Moq 抛出 "expected Invocation on the mock at least once"。在哪里设置一次,即使它被设置为空?

c# - c++/c# 编码结构以获取固定指针

c# - 将 signalr 与 web api 集成以向客户端推送通知

c# - 如何在使用 c# 在 aspx 上加载整页后延迟调用函数