【问题标题】:Moq - verify that no methods were calledMoq - 验证没有调用任何方法
【发布时间】:2011-03-11 12:31:38
【问题描述】:

这是我在 ASP.NET MVC 项目中的一个控制器使用 NUnit 和 Moq 进行的单元测试:

[Test]
public void Create_job_with_modelstate_errors_fails()
{
    var job = new JobDto();
    this.controller.ModelState.AddModelError("", "");

    ActionResult result = this.controller.Create(job);

    this.jobService.Verify(p => p.SaveJob(It.IsAny<JobDto>()), Times.Never());

    // some other asserts removed for brevity
}

这很好用,但从维护的角度来看,我认为这行比它需要的更冗长:

this.postService.Verify(p => p.SavePost(It.IsAny<PostDto>()), Times.Never());

我真正想做的是等价于...

this.postService.VerifyNoMethodsCalled();

...我感兴趣的是我的控制器没有调用服务上的任何方法。这可以使用 Moq 吗?

【问题讨论】:

标签: unit-testing mocking moq


【解决方案1】:

您可以使用 MockBehavior.Strict 创建 Mock,例如

this.postService = new Mock<IPostService>(MockBehavior.Strict);

这样,如果您不设置任何期望,对 this.postService 的任何调用都会失败

【讨论】:

  • 当您尝试模拟诸如 MVC 控制器上下文之类的东西时,它对于调试也非常方便,因为当您没有期望设置时它给您的错误消息比使用默认 MockBehavior.Loose 时获得的空引用异常
  • 我不明白这将如何允许“没有调用任何方法”验证。您是否还需要针对您不想调用的特定方法进行验证?或者也许我应该问在没有设置的测试方法结束时需要什么类型的“验证”。我的方法如下,但它不起作用: var mock = new Mock(MockBehavior.Strict) stu.DoSomething(); mock.Verify();
  • @bubbleking MockBehavior.Strict 意味着任何交互尝试都会立即抛出 MockException。 (除非您明确设置该交互)。所以不需要验证步骤。
  • 如果您发现您仍然需要验证调用才能使您的测试失败,这可能是因为您在程序中捕获了模拟抛出的异常。请记住,一旦您尝试获取属性、设置属性或调用模拟类型的方法,就会引发异常。
【解决方案2】:

现代答案(最小起订量 4.8 或更高版本):

mock.VerifyNoOtherCalls();

该方法确保除了任何先前验证的调用之外,没有进行任何调用。在这种特殊情况下,它之前没有 mock.Verify(...) 语句。因此,它将确保从不调用 mock。

如果有任何调用,您将收到这样的失败消息:

This mock failed verification due to the following unverified invocations:
...

这不需要使模拟严格。

来源:Moq Quickstart

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    相关资源
    最近更新 更多