0

Say I have a reference to a service called myService. It has a method called MyMethod which takes an int parameter.

Using Moq, I want to test a particular scenario that means MyMethod is called once with a specific value (let's say it's 3) and to also ensure that no other call is made.

If I wrote:

myService.Verify(o => o.MyMethod(It.IsAny<int>()), Times.Once);

Then this would ensure the method was only called once but I do not know if it was called with 3.

If I wrote:

myService.Verify(o => o.MyMethod(3), Times.Once);

Then this would ensure the method was only called once with 3 but I do not know if it was called any other times with values other than 3.

So, if I want to ensure both that it was only called once with a 3 and it was not called any other times then I would need to have two Verify calls like this:

myService.Verify(o => o.MyMethod(3), Times.Once);  
myService.Verify(o => o.MyMethod(It.IsAny<int>()), Times.Once); 

Is there any Moq convention that allows me to achieve the same thing with just one Verify call?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
millie
  • 2,642
  • 10
  • 39
  • 58
  • 1
    Create the mock in `Strict` mode and setup the mocked member `myService.Setup(_ => _.MyMethod(3));`. Now the verify for 3 only will work, and if the mocked member is called with anything other than what was setup it will fail – Nkosi Jun 21 '22 at 11:37
  • Just a small addition to Nkosi's comment. If you want to allow not just `3` but lets say 4 as well then you can use `.Setup(_ => _.MyMethod(It.Is(p => p == 3 || p == 4)))` – Peter Csala Jun 21 '22 at 11:39
  • I'd argue you are testing for two different situations: whether it is being called only once and whether it is being called with the value 3. I think it makes the test easier to understand if you make 2 calls to `Verify` rather than what @Nkosi is suggesting, which seems a bit too obscure. I wouldn't expect people to have to understand how Moq works to be able to understand what is being tested. – AsPas Jun 21 '22 at 11:40
  • Review the quick start here for how strict works https://github.com/Moq/moq4/wiki/Quickstart#customizing-mock-behavior – Nkosi Jun 21 '22 at 11:44
  • @AsPas I still believe it is one case being tested here. "Verify that only `MyMethod(3)` is being invoked" when exercising the test – Nkosi Jun 21 '22 at 11:46
  • @Nkosi it is one test case, but two different conditions. Personally, I feel like the test is more understandable if you make 2 calls to `Verify` instead of configuring the mock in an "unexpected" way. Specially because you can be more specific regarding fail messages. But this might just be me. – AsPas Jun 21 '22 at 11:50
  • What is "unexpected" here? You setup the expectation on the mock, and if that expectation is not met, the test fails. – Nkosi Jun 21 '22 at 11:52
  • To count how many times a method is called - use callback to keep track number of calls made (documented here - https://nodogmablog.bryanhogan.net/2021/07/two-ways-to-count-the-number-of-times-a-mocked-method-is-called-with-moq/). To ensure no other calls were made - use VerifyNoMethodsCalled documented here - https://stackoverflow.com/questions/3172998/moq-verify-that-no-methods-were-called . – Amogh Sarpotdar Jun 23 '22 at 08:29

0 Answers0