moq Validating call order with callbacks


Example

When you can't / don't want to use Strict Mocks, you can't use MockSequence to validate call order. An alternate approach is to use callbacks to validate that the Setup expectations are being invoked in the expected order. Given the following method to test:

public void MethodToTest()
{
    _utility.Operation1("1111");
    _utility.Operation3("3333");
    _utility.Operation2("2222");
}

It can be tested as follows:

// Create the mock (doesn't have to be in strict mode)
var utilityMock = new Mock<IUtility>();

// Create a variable to track the current call number
int callOrder = 1;

// Setup each call in the sequence to be tested.  Note that the callback validates that
// that callOrder has the expected value, then increments it in preparation for the next
// call.
utilityMock.Setup(x => x.Operation1(It.IsAny<string>()))
           .Callback(() => Assert.AreEqual(1, callOrder++, "Method called out of order") );
utilityMock.Setup(x => x.Operation2(It.IsAny<string>()))
           .Callback(() => Assert.AreEqual(2, callOrder++, "Method called out of order") );
utilityMock.Setup(x => x.Operation3(It.IsAny<string>()))
           .Callback(() => Assert.AreEqual(3, callOrder++, "Method called out of order") );


// Invoke the method to be tested
var sut = new SystemUnderTest(utilityMock.Object);
sut.MethodToTest();


// Validate any parameters that are important, note these Verifications can occur in any
// order.
utilityMock.Verify(x => x.Operation2("2222"));
utilityMock.Verify(x => x.Operation1("1111"));
utilityMock.Verify(x => x.Operation3("3333"));