Checking Call Order

In some cases, it may be important to check the correct calls sequence of methods, properties, and indexers inside system under test method. Assume that you have the following code:

public class SystemUnderTest
{
     private readonly IFoo _foo;

     public SystemUnderTest(IFoo foo)
     {
         if (foo == null)
             throw new ArgumentNullException();

         _foo = foo;
     }

     public void Execute()
     {
         var lastCommandName = _foo.LastCommandName;
         _foo.PrepareToExecute();
         _foo.Execute(lastCommandName);
         _foo.ReleaseResources();
         _foo.LastResult = 0;
     }
 }

 public interface IFoo
 {
     string LastCommandName { get; }

     int LastResult { get; set; }

     void PrepareToExecute();

     void Execute(string command);

     void ReleaseResources();
 }

You need to test the correctness of the SystemUnderTest.Execute() method, which in your case is the correct order of IFoo members calls. To check the method and properties calls order you must use Verify.Order, as in the example below:

[Test]
[TrueFake]
public void Execute_SimpleCall_CallOrderIsCorrect()
{
    // Arrange.
    var fooFake = TrueFake.Of<IFoo>();
    var sut = new SystemUnderTest(fooFake);

    // Act.
    sut.Execute();

    // Assert.
    Verify.Order
        .Call(() => fooFake.LastCommandName)
        .Call(() => fooFake.PrepareToExecute())
        .Call(() => fooFake.Execute(Arg.Any))
        .Call(() => fooFake.ReleaseResources())
        .Set(() => fooFake.LastResult, 0);
}

where Verify.Order.Call is responsible for checking the method call or property (indexer) get accessor; Verify.Order.Set - for checking property (indexer) set accessor.

Please note that you can also use argument matchers when writing call order.

NOTE: When checking the call order you do not have to specify all calls within the test method. You just need to specify only the key calls which you want to verify.

According to this, you would like to rewrite Verify.Order code block as follows:

Verify.Order
        .Call(() => fooFake.LastCommandName)
        .Call(() => fooFake.Execute(Arg.Any))
        .Set(() => fooFake.LastResult, 0);

This code block verifies that firstly the LastCommandName property must be read, then Execute method with any argument must be called and finally LastResult property must be set to “0”. Despite this SystemUnderTest.Execute() method can have any code block between reading LastCommandName property and calling Execute method.