如何验证在Moq中没有调用该方法?

ale*_*lex 439 .net c# moq

如何验证在Moq中未调用该方法?

它有像AssertWasNotCalled这样的东西吗?

更新:从3.0版开始,可以使用新语法:

mock.Verify(foo => foo.Execute("ping"), Times.Never());
Run Code Online (Sandbox Code Playgroud)

Dan*_*ann 507

在具有Times.Never枚举集的测试之后运行验证.例如

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());
Run Code Online (Sandbox Code Playgroud)

  • 这里的关键是在调用mock之后,Verify(action,Never)调用是*.我以为它是为稍后调用VerifyAll()设置验证(*不*工作) (3认同)

Dan*_*ish 146

更新:从第3版开始,检查上述问题的更新或Dann的答案如下.

或者,使你的模拟严格,如果你调用一个你没有期望的方法,它将失败

new Mock<IMoq>(MockBehavior.Strict)
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望模拟松动,请使用.Throws(例外)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Run Code Online (Sandbox Code Playgroud)

  • 这不是真正的"验证未被调用",因为它可以在方法中被捕获并且仍然可以工作 - 提供误报! (46认同)
  • ...或Callback()设置一些可以断言的标志. (8认同)
  • Expect现已弃用 (4认同)
  • 这可能是2009年最好的方式,但现在肯定不是.抱歉 (4认同)
  • 同样使用选项#2,您不能在常规拆解方法中使用VerifyAll - 它将无法表示未满足期望; 当测试理想地通过时. (2认同)

Chr*_*sic 41

被盗:约翰福斯特回答问题,"需要帮助更好地了解Moq"

您可能想要测试的一件事是,当65岁以上的人被传入方法时,不会调用pay方法

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {

    var mockPensionService = new Mock<IPensionService>();

    var person = new Person("test", 66);

    var calc = new PensionCalculator(mockPensionService.Object);

    calc.PayPensionContribution(person);

    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}
Run Code Online (Sandbox Code Playgroud)


mih*_*iha 9

这在Moq的最新版本中不起作用(因为至少3.1),它应该Verify在答案中提到的方法中指定.

实际上,最好.AtMost(0)在返回语句后指定.

var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);
Run Code Online (Sandbox Code Playgroud)

虽然"投掷"也有效,但AtMost(0)恕我直言更具表现力.

  • 在Moq v3.1中找不到这个 (2认同)

Mar*_*ese 6

使用VerifyNoOtherCalls(需要 Moq 4.8 或更高版本)

这个答案是一种间接的方法。您无需检查是否未调用特定方法,而是检查一般情况下是否未进行意外调用。

考虑一下对模拟的彻底测试会做两件事:

  1. 验证是否已拨打所有预期的电话
  2. 确认没有拨打意外电话

如果您已经执行了步骤 1,那么添加步骤 2 就很简单:

// Step 1 (if relevant - see note below)
mock.Verify(..., Times.Exactly(2));
mock.Verify(..., Times.Once());
// ...

// Step 2
mock.VerifyNoOtherCalls();
Run Code Online (Sandbox Code Playgroud)

笔记

  • 如果省略步骤 1,步骤 2 将仅确保根本没有对模拟进行任何调用。
  • 这不需要严格的模拟。
  • 来源:起订量快速入门