Moq - 验证没有调用任何方法

ric*_*eym 35 unit-testing moq mocking

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

[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
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但从维护的角度来看,我认为这一行比它需要的更冗长:

this.postService.Verify(p => p.SavePost(It.IsAny<PostDto>()), Times.Never());
Run Code Online (Sandbox Code Playgroud)

我真正希望能够做的是......

this.postService.VerifyNoMethodsCalled();
Run Code Online (Sandbox Code Playgroud)

...因为我感兴趣的是我的控制器不会调用服务上的任何方法.这可能使用Moq吗?

Pat*_*ald 45

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

this.postService = new Mock<IPostService>(MockBehavior.Strict);
Run Code Online (Sandbox Code Playgroud)

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

  • @bubbleking MockBehavior.Strict意味着任何交互尝试都会立即抛出MockException.(除非您明确设置该交互).因此不需要验证步骤. (2认同)

Mar*_*ese 9

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

mock.VerifyNoOtherCalls();
Run Code Online (Sandbox Code Playgroud)

该方法确保除了任何先前验证的调用之外,不会进行任何调用。mock.Verify(...)在本例中,前面没有任何语句。因此,它将确保模拟从未被调用过。

如果进行任何调用,您将收到如下失败消息:

This mock failed verification due to the following unverified invocations:
...
Run Code Online (Sandbox Code Playgroud)

这不需要使模拟变得严格。

来源:起订量快速入门