52

This is a unit-test from one of my controllers in an ASP.NET MVC project, using NUnit and 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 works fine, but from a maintenance point of view I think this line is more verbose than it needs to be:

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

What i'd really like to be able to do is something equivalent to...

this.postService.VerifyNoMethodsCalled();

...as all i'm interested in is that my controller doesn't call any methods on the service. Is this possible using Moq?

SteveC
  • 15,808
  • 23
  • 102
  • 173
richeym
  • 4,049
  • 3
  • 24
  • 23
  • 4
    Google searchers: If you're interested in verifying that just a SINGLE, PARTICULAR method was not called, this is the question you want instead: http://stackoverflow.com/questions/537308/how-to-verify-that-method-was-not-called-in-moq – Jon Schneider Feb 11 '16 at 20:14

2 Answers2

59

You could create the Mock with MockBehavior.Strict, e.g.

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

That way, if you don't Setup any expectations, any calls to this.postService will fail

Patrick McDonald
  • 64,141
  • 14
  • 108
  • 120
  • 1
    It's very handy also for debugging when you're trying to mock something like an MVC controller context, as the error message it gives you when you don't have an expectation setup is much more intuitive than the null reference exceptions you get when using the default MockBehavior.Loose – Patrick McDonald Jul 05 '10 at 21:26
  • I don't see how this will allow a "no methods were called" verification. Won't you still have to verify against specific methods you don't want called? Or perhaps I should be asking what type of "Verifiy" one needs at the end of a test method that has no setups. My approach is below and it doesn't work: var mock = new Mock(MockBehavior.Strict) stu.DoSomething(); mock.Verify(); – bubbleking Oct 20 '15 at 15:15
  • 2
    @bubbleking The MockBehavior.Strict means that any interaction attempt will immediately throw a MockException. (Unless you explicitly Setup that interaction). So no verification step is needed. – Iain Feb 18 '16 at 04:34
  • If you find that you still need to verify the calls to get you're tests to fail, it could be because you are catching the exception thrown by the mock in you program. Remember, an exception will be thrown as soon as you try to get a property, set a property, or invoke a method on the mocked type. – Nechemia Hoffmann Jul 23 '20 at 19:13
7

Modern answer (Moq 4.8 or later):

mock.VerifyNoOtherCalls();

That method makes sure no calls were made except for any previously verified ones. In this particular case, there are no mock.Verify(...) statements before it. Thus, it will make sure the mock was never called at all.

You will get a failure message like this if any calls were made:

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

This does not require making the mock strict.

Source: Moq Quickstart

MarredCheese
  • 17,541
  • 8
  • 92
  • 91