How to verify that a method has been called exactly once with Moq?

How to verify that a method has been called exactly once with Moq? Thing Verify() vs. Verifable() really confusing.

+102
moq mocking
Nov 17 '10 at 15:48
source share
3 answers

You can use Times.Once() or Times.Exactly(1) :

 mockContext.Verify(x => x.SaveChanges(), Times.Once()); mockContext.Verify(x => x.SaveChanges(), Times.Exactly(1)); 

Here are the methods of the Times class:

  • AtLeast - Indicates that the bullying method should be called at least once.
  • AtLeastOnce - Indicates that the bullying method should be called at least at least.
  • AtMost - Indicates that the mocked method should be called just at the maximum time.
  • AtMostOnce - Indicates that the mocked method should be called once at maximum.
  • Between - indicates that the mocked method should be called between and from time to time.
  • Exactly - Indicates that the bullying method should be called exactly once.
  • Never - Indicates that the mocked method should not be called.
  • Once - indicates that the method of bullying should be called exactly once.

Just remember that these are method calls; I kept stumbling, thinking they were properties and forget the parentheses.

+151
Nov 17 '10 at 16:41
source share

Imagine we are building a calculator with one method to add 2 integers. Let's imagine further that when calling the add method, it calls the print method once. Here is how we can verify this:

 public interface IPrinter { void Print(int answer); } public class ConsolePrinter : IPrinter { public void Print(int answer) { Console.WriteLine("The answer is {0}.", answer); } } public class Calculator { private IPrinter printer; public Calculator(IPrinter printer) { this.printer = printer; } public void Add(int num1, int num2) { printer.Print(num1 + num2); } } 

And here is the test itself with comments in the code for further clarification:

 [TestClass] public class CalculatorTests { [TestMethod] public void WhenAddIsCalled__ItShouldCallPrint() { /* Arrange */ var iPrinterMock = new Mock<IPrinter>(); // Let mock the method so when it is called, we handle it iPrinterMock.Setup(x => x.Print(It.IsAny<int>())); // Create the calculator and pass the mocked printer to it var calculator = new Calculator(iPrinterMock.Object); /* Act */ calculator.Add(1, 1); /* Assert */ // Let make sure that the calculator Add method called printer.Print. Here we are making sure it is called once but this is optional iPrinterMock.Verify(x => x.Print(It.IsAny<int>()), Times.Once); // Or we can be more specific and ensure that Print was called with the correct parameter. iPrinterMock.Verify(x => x.Print(3), Times.Once); } } 

Note. By default, Moq drowns out all properties and methods as soon as you create a Mock object. Therefore, without even calling Setup , Moq has already IPrinter methods for IPrinter , so you can just call Verify . However, as a good practice, I always configure it because we may need to force the parameters to the method to meet certain expectations, or the return value from the method to match certain expectations or the number of calls to it.

+8
Apr 09 '18 at 19:41
source share

The control controller may be:

  public HttpResponseMessage DeleteCars(HttpRequestMessage request, int id) { Car item = _service.Get(id); if (item == null) { return request.CreateResponse(HttpStatusCode.NotFound); } _service.Remove(id); return request.CreateResponse(HttpStatusCode.OK); } 

And when the DeleteCars method is called with a valid identifier, we can verify that the Service remove method called in this test exactly once:

  [TestMethod] public void Delete_WhenInvokedWithValidId_ShouldBeCalledRevomeOnce() { //arange const int carid = 10; var car = new Car() { Id = carid, Year = 2001, Model = "TTT", Make = "CAR 1", Price=2000 }; mockCarService.Setup(x => x.Get(It.IsAny<int>())).Returns(car); var httpRequestMessage = new HttpRequestMessage(); httpRequestMessage.Properties[HttpPropertyKeys.HttpConfigurationKey] = new HttpConfiguration(); //act var result = carController.DeleteCar(httpRequestMessage, vechileId); //assert mockCarService.Verify(x => x.Remove(carid), Times.Exactly(1)); } 
+2
Dec 14 '16 at 20:59
source share



All Articles