Verifying the execution order with unit tests


Verifying the execution order with unit tests

Before anything, let’s get something clear: this post is not about the execution order of unit tests, since I strongly recommend you not to do it, as you can read more about here. It’s about verifying the execution order with unit tests of the methods inside a specific method. And why would I want that, you might ask? Well, sometimes you need to do more than just verify that the correct methods are called. For example, let’s suppose you are implementing the BreakfastRoutine method in your Human class. It would be really good to be sure that he would always brush his teeth after eating, right? I for one believe that my implementation of this method fails sometimes.

How to do it

In order to do that, we can take advantage of Moq’s Callback feature. Simply put, it’s something that allows us to execute a piece of code right after a method has been called. With it, we can set up a flag to keep track of when a method has been invoked, and then consume that flag to verify if the second method has been called at the right time. Continuing with our breakfast example, let’s see how it would like in the code.

Here is our Human.cs:

public class Human
{
    public IHygieneFunctions HygieneFunctions { get; }
    public IMouthStuff MouthStuff { get; }

    public Human(IHygieneFunctions hygieneFunctions, IMouthStuff mouthStuff)
    {
        HygieneFunctions = hygieneFunctions;
        MouthStuff = mouthStuff;
    }

    public void BreakfastRoutine()
    {
        MouthStuff.ChewYummyYummies();
        HygieneFunctions.BrushTeeth();
    }
}

Simple, right? And this would be our test:

[Test]
public void BreakfastRoutine_ShouldBrushTeethAfterEating()
{
    //Arrange
    var hygieneFunctionsMock = new Mock<IHygieneFunctions>();
    var mouthStuffMock = new Mock<IMouthStuff>();
    var human = new Human(hygieneFunctionsMock.Object, mouthStuffMock.Object);

    var hasChewed = false;
    var teethBrushedAfterChewing = false;
    mouthStuffMock.Setup(x => x.ChewYummyYummies()).Callback(() => hasChewed = true);
    hygieneFunctionsMock.Setup(x => x.BrushTeeth()).Callback(() => teethBrushedAfterChewing = hasChewed);

    //Act
    human.BreakfastRoutine();

    //Assert
    Assert.That(teethBrushedAfterChewing, Is.True);
}

So, what’s going on is:

  1. We create our mocks and our Human
  2. We set a callback for the ChewYummyYummies method, so when it’s called, it will set the hasChewed flag to true
  3. We also set a callback for the BrushTeeth method, so it will only be true if the hasChewed variable is true, which allows us to verify what we want

Conclusion

Pretty simple right? With just some lines of logic, we are verifying the execution order with unit tests, saving our beloved human from having to brush twice and possibly missing his train. Even better, we didn’t even have to modify our code to reach our objective, keeping our solutions as pure as possible.