Overview
Credit: https://docs.educationsmediagroup.com/unit-testing-csharp/moq
Verifications are conducted after production code has been called. They verify that a certain method/property was called with specific arguments.
Test examples below use this interface:
public interface IService
{
void Send(string message);
Task SendAsync(string message);
event EventHandler<MessageEventArgs> Sent;
string ContentType { get; set; }
}
Implicit Verification
The implicit approach involves calling Verifiable()
at the end of each configuration to mark the mock to be verified:
// ARRANGE
// When using this approach, configure mocks with expected parameters as much as possible...
mock.Setup(p => p.Send("Hello word")).Verifiable("Optional custom failure message");
// ASSERT
// ...and rely on implicit verification as much as possible:
mock.VerifyAll(); // Verify all configurations enriched with `Verifiable()` on a single mock were invoked
Mock.Verify(mock, anotherMock, yetAnotherMock); // Verify all configurations enriched with `Verifiable()` on several mocks were invoked
mock.VerifyNoOtherCalls(); // Verify that no other invocations were made other than those already verified
Implicit Verification for Properties
mock.SetupProperty(p => p.ContentType, "text/plain").Verifiable();
mock.SetupGet(p => p.ContentType).Returns("text/plain").Verifiable();
mock.SetupSet(p => p.ContentType = It.IsAny<string>()).Verifiable();
Explicit Verification
The explicit approach involves calling Verify()
on a standalone line.
// When using this approach, configure mocks with matchers as much as possible...
mock.Setup(p => p.Send(It.IsAny<string>()));
// ...and rely on explicit verification with constraints as much as possible:
mock.Verify(p => p.Send("Hello world"), Times.Once())
Explicit Verification for Properties
mock.VerifyGet(p => p.ContentType, Times.Once());
mock.VerifySet(p => p.ContentType = "text/plain", Times.Once());
Times
The Times
class has static methods that can constrain the amount of invocations to expect:
Times.Exactly(3)
Times.AtLeast(3)
Times.AtMost(3)
Times.Between(3, 5, Range.Inclusive)
Times.Between(2, 4, Range.Exclusive)
Times.Never()
Times.Once()
Times.AtLeastOnce()
Times.AtMostOnce()
Verifying Event Handling
mock.VerifyAdd(p => p.Sent += It.IsAny<EventHandler<MessageEventArgs>>());
mock.VerifyRemove(p => p.Sent -= It.IsAny<EventHandler<MessageEventArgs>>());