I can not figure out what is used Mock.Verifiable() , if I understand correctly, this code:

 var mockContainer = new Mock<CloudBlobContainer>(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny<string>())) .Returns(mockBlobItem.Object); // ... mockContainer.Verify(c => c.GetBlockBlobReference(It.IsAny<string>()), Times.AtLeastOnce); 

It will be equivalent to this:

 var mockContainer = new Mock<CloudBlobContainer>(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny<string>())) .Returns(mockBlobItem.Object) .Verifiable(); // ... mockContainer.Verify(); 

There is a third option:

 var mockContainer = new Mock<CloudBlobContainer>(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny<string>())) .Returns(mockBlobItem.Object); // ... mockContainer.Verify(); 

I studied many examples, and so the second or third options are used there, as a rule. And there is also .VerifyAll() .

  1. How to and why?
  2. What are the features and pitfalls?
  3. How do these options affect the behavior of Strict and Loose ?

I could not find the documentation for Moq ( except for this inferior one ), does it even exist?

    1 answer 1

    Yes, you understood correctly.

    As far as can be judged from the article, this method can be used to verify a call to a previously called method defined in Setup.

     var thing = new Thing() { Id = 1 }; var mockMapper = new Mock<IThingMapper>(); mockMapper.Setup(p => p.Save(thing)).Verifiable(); // do stuff mockMapper.Verify(); 

    In addition, according to the English answer, it is advisable not to use this approach because it is clearly contrary to the AAA pattern. The contradiction lies in the fact that the preparation of data for testing (Arrange) and the description of what should be checked (Assert) occurs in the Setup method.

    The project maintainers themselves voice more happy cases why you should not continue to develop such an API.

    Nevertheless, this approach can be justified, for example, by the need to avoid duplicate code.

    The only case where this approach cannot be used is to check the number of calls if necessary. In this case, you can only use the Verify method with a full description of the expected call:

     mock.Verify(c => c.Method(It.Is<string>(x => x == "x")), Times.Once); 

    Regarding the use of Verify without parameters. It will only check the methods that you noted in the setup using the Verifiable method:

     var mockContainer = new Mock<CloudBlobContainer>(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny<string>())) .Returns(mockBlobItem.Object) .Verifiable(); // ... mockContainer.Verify(); 

    If you want to check if the method that was not marked as Verifiable was called , you can use the VerifyAll method:

     var mockContainer = new Mock<CloudBlobContainer>(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny<string>())) .Returns(mockBlobItem.Object); // ... // Verify - не будет проверять в этом случае // т.к. Вы не получите ошибку даже если метод не был вызван ни разу // для такого случая можно сделать так mockContainer.VerifyAll(); 

    But personally, I would not use VerifyAll, if only because it is not at all obvious.


    Development is conducted on a githaba and in addition to the detailed documentation for which you referred there is a quick start and examples of use .

    • This is all I read. Can you explain the difference in using / not using Verifiable ? Can you explain exactly how this approach violates the principle of AAA ? - Anatol
    • In the case of using the Verifiable () method, you can check all the method calls previously defined in the Setup () method and then, when calling Verify (), check whether these methods were called. The AAA pattern implies explicit call checking. In fact, in the Assert section, you need to explicitly call the Verify method with the expected parameters (as you did in Setup ) and the expected number of calls. - Liashenko V
    • What is the difference between the second and third options in the question? How is VerifyAll() ? a quick start gives a very superficial idea and makes you think out a lot of things that aren't right - Anatol
    • one
      @Anatol running through the code: the third option will not check whether the method was called or not. The difference in the Verify (without parameters) and VerifyAll methods (I open the pandora's box) is that the latter checks to see if all captured methods have been called at least once. Those. VerifyAll can be used in the third case. In the evening I will check "in work" and correct the answer. PS: Thanks for the interesting question and genuine inteers. Most interesting. In the evening I will add the answer. - Liashenko V