Better testing experience with Shouldly

Shouldly Logo
Shouldly Logo

I am a strong believer in unit testing, I like to write lots of tests for my code in order to make sure I do not regress when implementing new features on my projects. I love having a safety net when working.

Then it is important to make sure that the tests are easy to write and that they give a good feedback when failing. When a test fails you should be able to know exactly where the code under test has an incorrect behavior to fix it as soon as possible.

Shouldly is a .NET assertion library very helpful for this matter, it provides a lot of extensions for various types making them easy to test. It is available on GitHub and as a Nuget package:

Install-Package Shouldly

Simple assertions

Let’s dive into the topic to see how it can be used, I’ll start with simple assertions on an integer value:

var value = 5;
value.ShouldBe(5);
value.ShouldBeGreaterThan(4);
value.ShouldBeGreaterThanOrEqualTo(5);
value.ShouldBeInRange(0, 10);
value.ShouldBeLessThan(6);
value.ShouldBeOneOf(2, 5, 7);

It is as simple as that, not need for any Assert method, Shouldly does it for you. And there are many more extensions to test about everything you want.

Now, we can have a look at the assertions available for the string type:

var myString = "foo";
myString.ShouldNotBeEmpty();
myString.ShouldNotBe(null);
myString.ShouldStartWith("f");
myString.ShouldEndWith("oo");
myString.ShouldNotContain("bar");
myString.ShouldBe("FOO", Case.Insensitive);

Likewise, Shouldly offers various methods in order to test a string value to make sure everything behaves as expected.

The library offers also some assertions to check the behavior of a method through actions:

Should.NotThrow(() => SuccessMethod());
Should.CompleteIn(() => SuccessMethod(), TimeSpan.FromMilliseconds(50));

As you can see you can write performances tests for your methods using the CompleteIn() method.

Specific error messages

Now that we have written some tests using Shouldly, let’s have a look at what happens when a test fails. As I said it is important to have comprehensive error messages when an error occurred in order to be able to debug quickly.

int value = 5;
value.ShouldBeGreaterThan(6);

Of course this test fails, and generates the following error message:

    value
        should be greater than
    6
        but was
    5

I find that this message is quite clear and gives us a good understanding of what went wrong, it even contains the name of the tested variable. Now let’s see how is the message with an enumerable.

var numbers = new[] { 1, 2, 4 };
numbers.ShouldBe(new []{1, 2, 3});
    numbers
        should be
    [1, 2, 3]
        but was
    [1, 2, 4]
        difference
    [1, 2, *4*]

The library highlights the difference for us, again I find the message pretty clean, especially when you compare it with the MSTest version:

var numbers = new[] { 1, 2, 4 };
CollectionAssert.AreEqual(new[] { 1, 2, 3 }, numbers);
CollectionAssert.AreEqual failed. (Element at index 2 do not match.)

Here are a few more examples.

Should.NotThrow(() => FailingMethod());
    Should
        not throw 
    System.ApplicationException
        but does
Should.CompleteIn(() => LongMethod(), TimeSpan.FromMilliseconds(50));
    Task
        should complete in
    00:00:00.0500000
        but did not

Shouldly is easy to install and easy to use and, in my opinion, makes testing code much clearer. It provides a lot of helpful extensions and if you find that one is missing you can contribute to the project to make it available to everyone.

I think that testing code should be treated with the same respect than production code and this is why it should me made as clean as possible and as understandable as possible, this way your tests are a part of the documentation of your code.

See you next time!

Testing Akka.NET actors with Akka.TestKit

In my last blog post I introduced the actor model using the Akka.NET framework. And since I like to write unit tests for my projects I was wondering how to test the few actors I have created even if there is not much logic inside them.

I believe that understanding how to write tests for a given technology early is important in order to avoid creating too much coupling. And also tests provide rapid feedback helping us to debug what we are creating, if you can debug quickly you can learn quickly.

When working with Akka.NET, you can use Akka.TestKit to write the tests for your actor system. Then there are several nuget packages depending on the testing framework you use.

Install-Package Akka.TestKit.VsTest

Install-Package Akka.TestKit.NUnit

Install-Package Akka.TestKit.Xunit

In my case I will use the VsTest package for MSTest.

Writing your first test

I will start by testing the behavior of the BlueActor, here is its definition:

public class BlueActor : ReceiveActor
{
    private const string ActorName = "BlueActor";
    private const ConsoleColor MessageColor = ConsoleColor.Blue;
 
    private int _counter = 0;
 
    protected override void PreStart()
    {
        base.PreStart();
        Become(HandleString);
    }
 
    private void HandleString()
    {
        Receive<string>(s =>
        {
            PrintMessage(s);
            _counter++;
            Sender.Tell(new MessageReceived(_counter));
        });
    }
 
    private void PrintMessage(string message)
    {
        Console.ForegroundColor = MessageColor;
        Console.WriteLine(
            "{0} on thread #{1}: {2}",
            ActorName,
            Thread.CurrentThread.ManagedThreadId,
            message);
    }
}

As you can see, there is not much to test, I can’t really test that the actor is writing something on the Console. But I might be able to test that it replies to the sender with a message containing a counter.

In my example the sender was an instance of a GreenActor but in a testing context it does not have to be that way. Let’s use TestKit to write a test.

[TestClass]
public class BlueActorTests : TestKit
{
    [TestCleanup]
    public void Cleanup()
    {
        Shutdown();
    }
 
    [TestMethod]
    public void BlueActor_Respond_With_Counter()
    {
        var actor = ActorOfAsTestActorRef<BlueActor>();
        actor.Tell("test");
        var answer = ExpectMsg<MessageReceived>();
        Assert.AreEqual(1, answer.Counter);
    }
}

The test class inherits from TestKit in order to access a set of functionalities allowing to test an actor. Since an actor “lives” inside an actor system in an asynchronous way, it would be a real pain to mock everything, TestKit does it for us.

I can now use the ActorOfAsTestActorRef<T> method in order to get an IActorRef wrapped in a specific instance dedicated to testing. In this context the message sender is the test class, I can then test that the actor replies with a MessageReceived instance. To do so I can use the ExpectMsg<T> method to do the check and to retrieve the message, if there is no message of this type the test fails.

It is also important to call the Shutdown method after running the tests in order to dispose of the actor system without risking to produce memory leak.

Testing another actor

I will now write a test for the YellowActor, see definition below.

public class YellowActor : UntypedActor
{
    private const string ActorName = "YellowActor";
    private const ConsoleColor MessageColor = ConsoleColor.Yellow;
 
    private IActorRef _greenActor;
 
    protected override void PreStart()
    {
        base.PreStart();
 
        _greenActor = Context.ActorOf<GreenActor>();
    }
 
    protected override void OnReceive(object message)
    {
        if (message is string)
        {
            var msg = message as string;
 
            PrintMessage(msg);
            _greenActor.Tell(msg);
        }
    }
 
    private void PrintMessage(string message)
    {
        Console.ForegroundColor = MessageColor;
        Console.WriteLine(
            "{0} on thread #{1}: {2}",
            ActorName,
            Thread.CurrentThread.ManagedThreadId,
            message);
    }
}

There is no reply to check, this actor just transfer the message to another actor after printing it. I can still write a test if I want.

[TestClass]
public class YellowActorTests : TestKit
{
    [TestCleanup]
    public void Cleanup()
    {
        Shutdown();
    }
 
    [TestMethod]
    public void YellowActor_Should_Not_Answer()
    {
        var actor = ActorOfAsTestActorRef<YellowActor>();
        actor.Tell("test");
        ExpectNoMsg();
    }
}

In this test I use the ExpectNoMsg method to verify that the actor does not answer. The test pass but I would like to test that the message is transferred to another actor. Unfortunately at the moment I cannot (or I did not find the way to do it) without changing the code of the actor.

The greenActor IActorRef is created by the actor itself and therefore is not a TestActorRef. To change this, I will inject the actor reference in the constructor, this way I will be able to use a testing reference when running tests. I add the following constructor to the YellowActor class:

public YellowActor(IActorRef greenActor)
{
    _greenActor = greenActor;
}

And I remove the PreStart method. At this point the code does not compile, I have to update the code creating the actor.

var yellowProps = Props.Create<YellowActor>(actorSystem.ActorOf<GreenActor>());
var yellowActor = actorSystem.ActorOf(yellowProps);

This is one of several way to inject dependencies to an actor. And I can now update my test to check that a message is sent.

[TestMethod]
public void YellowActor_Should_Send_String_Message()
{
    var props = Props.Create<YellowActor>(TestActor);
    var actor = ActorOfAsTestActorRef<YellowActor>(props);
    actor.Tell("test");
    var message = ExpectMsg<string>();
    StringAssert.Equals("test", message);
}

I used the TestActor property available in the test class as dependency for the yellow actor. And now I am able to verify that a message is sent using the ExpectMsg method. If I had let the ExpectNoMsg method the test would have failed because the actor system in my test context has received a message.

This is the end of this small introduction to testing with Akka.TestKit for Akka.NET.

Wrapping up

I am definitely not an expert regarding Akka.NET and even less with actor testing, so if you find mistakes regarding my approach feel free to teach me. I wanted to introduce testing early in order to make me think deeper when using Akka.NET. From this experience I learned that the actor model works as a whole and it is something to consider in order to avoid making mistakes.

I am also glad to have been able to write some tests for my actors without too much pain using the tool provided by the community, big thank to them for the hard work.

I will continue my journey with this technology and I will share my thoughts with blog posts. There is much to discover and to learn.

See you next time!

The Actor Model with Akka.NET

akkadotnet-logoA few weeks ago I discovered a framework implementing the actor-model: Akka.NET. Since I was quite unaware regarding this programming model, I decided to give it a try. I really like what I saw and the concepts behind the actor-model and this is why I’m creating this blog post.

The actor-model adopts the idea that everything is an actor, an actor is an entity that receive messages, creates other actors and adapts its behavior depending on the message it receives. And the entire system relies on asynchronous communication making it inherently concurrent.

Akka.NET is an open-source project (available on GitHub) bringing the actor-model to the .NET world (C# & F#), it is based on the Akka framework (Scala & Java).

To install Akka.NET for one of your project, you just have to install a nuget package:

Install-Package Akka

Creating your first actor

I will now show you how to use the project to create your first actor-model. You’ll find below the definition of an actor in C#.

public class YellowActor : UntypedActor
{
    private const string ActorName = "YellowActor";
    private const ConsoleColor MessageColor = ConsoleColor.Yellow;
 
    protected override void OnReceive(object message)
    {
        if (message is string)
        {
            var msg = message as string;
            PrintMessage(msg);
        }
    }
 
    private void PrintMessage(string message)
    {
        Console.ForegroundColor = MessageColor;
        Console.WriteLine(
            "{0} on thread #{1}: {2}",
            ActorName,
            Thread.CurrentThread.ManagedThreadId,
            message);
    }
}

In this case I created a class that inherits from UntypedActor, this allow me to override the OnReceive method. This way the system knows that this class represents an actor able to treat messages. Creating a basic actor is simple, I don’t need to write too much code.

As you can see the OnReceive method is protected, if I want to use this actor I will have to create an actor system, I cannot just instantiate this class to use it. Akka.NET provides a set of functionalities to deal with the actor model, the ActorSystem is one of them. This is how you create a system and an actor:

var actorSystem = ActorSystem.Create("myActorSystem");
 
var yellowActor = actorSystem.ActorOf<YellowActor>();
 
actorSystem.AwaitTermination();

Since my actor is quite simple, I don’t need more code to have an up-and-running actor system with an actor. The WaitTermination method blocks the current thread to avoid it to exit the program, it waits for the actor system to shut down.

Now I can send a message to the actor to see what will happen. To do so I will add the following lines:

Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Starting actor system on thread: {0}", Thread.CurrentThread.ManagedThreadId);
 
yellowActor.Tell("Message to yellow");

Let’s run the application to see what is happening.

YellowActor

The YellowActor has received the message and has printed it, on a different thread, which makes sense since the one that has created the actor system is blocked by this same system.

There is one important concept to know when manipulating actors with Akka.NET, in my example the yellowActor variable is not an instance of YellowActor, it is an IActorRef. Sending messages to actors is always done with reference, the framework will know how to deliver the message to the associated actor.

Adding a second actor

Now that we have a working actor I will add a second one which will be used by the YellowActor. This way I will show you how to “create” an actor from another one. Let’s define a GreenActor:

public class GreenActor : ReceiveActor
{
    private const string ActorName = "GreenActor";
    private const ConsoleColor MessageColor = ConsoleColor.Green;
 
    protected override void PreStart()
    {
        base.PreStart();
 
        Become(HandleString);
    }
 
    private void HandleString()
    {
        Receive<string>(s =>
        {
            PrintMessage(s);
        });
    }
 
    private void PrintMessage(string message)
    {
        Console.ForegroundColor = MessageColor;
        Console.WriteLine(
            "{0} on thread #{1}: {2}",
            ActorName,
            Thread.CurrentThread.ManagedThreadId,
            message);
    }
}

This time I made the class inherits from ReceiveActor allowing me to use the Receive<T> property telling the actor how to handle different types of message, in my case it’s still a string.

Now I will update the YellowActor to use this new actor.

private IActorRef _greenActor;
 
protected override void PreStart()
{
    base.PreStart();
 
    _greenActor = Context.ActorOf<GreenActor>();
}
 
 
protected override void OnReceive(object message)
{
    if (message is string)
    {
        var msg = message as string;
 
        PrintMessage(msg);
        _greenActor.Tell(msg);
    }
}

The actor has an IActorRef field “pointing” toward the green actor. This actor will not only print the message it receives but it will also send it to the green actor. Let’s see what we have now.

GreenActor

The new actor has received the message and treat it on a different thread. I just show you how to easily create actors and how to pass messages between them. You might think that the second actor looks more complicated for the work it does, and you are right! Yet it will come handy in just a minute when we will create a third actor.

One more actor

It is time to create the BlueActor, again this actor will display the message it receives. And will also respond with a message telling how many messages it has displayed. Here is the blue actor:

public class MessageReceived
{
    public int Counter { get; private set; }
 
    public MessageReceived(int counter)
    {
        Counter = counter;
    }
}
 
public class BlueActor : ReceiveActor
{
    private const string ActorName = "BlueActor";
    private const ConsoleColor MessageColor = ConsoleColor.Blue;
 
    private int _counter = 0;
 
    protected override void PreStart()
    {
        base.PreStart();
        Become(HandleString);
    }
 
    private void HandleString()
    {
        Receive<string>(s =>
        {
            PrintMessage(s);
            _counter++;
            Sender.Tell(new MessageReceived(_counter));
        });
    }
 
    private void PrintMessage(string message)
    {
        Console.ForegroundColor = MessageColor;
        Console.WriteLine(
            "{0} on thread #{1}: {2}",
            ActorName,
            Thread.CurrentThread.ManagedThreadId,
            message);
    }
}

To send back a message inside an actor, you can use the Sender property which is an IActorRef “pointing” to the actor which sent the message. This is helpful if you have an actor hierarchy where a high-level actor delegates some work to lower-level actors.

It is time to update the GreenActor to make it use the BlueActor and to make it handle the MessageReceived type of message, the following code is added to the class:

private const ConsoleColor ResponseColor = ConsoleColor.DarkGreen;
 
private IActorRef _blueActor;
 
protected override void PreStart()
{
    base.PreStart();
 
    var lastActorProps = Props.Create<BlueActor>();
    _blueActor = Context.ActorOf(lastActorProps);
 
    Become(HandleString);
}
 
private void HandleString()
{
    Receive<string>(s =>
    {
        PrintMessage(s);
        _blueActor.Tell(s);
    });
 
    Receive<MessageReceived>(m => PrintResponse(m));
}
 
private void PrintResponse(MessageReceived message)
{
    Console.ForegroundColor = ResponseColor;
    Console.Write("{0} on thread #{1}: ",
        ActorName,
        Thread.CurrentThread.ManagedThreadId);
    Console.WriteLine("Receive message with counter: {0}",
        message.Counter);
}

I was able to use Receive again to specify how to handle MessageReceived instances, an actor can handle several types of message. An actor can even send messages to itself using the Self property. Let’s try out our actor system.

BlueActor

All three actors have displayed the message and the green actor has received an answer from the blue actor. Let’s see if the counter is working as expected, we will tell the program to send 5 messages to the yellow actor.

SeveralMessages

The green actor received a message from the blue actor with a counter of 5, looks good! The actors communicate with each other using different threads.

Time to conclude

This blog post is just an introduction of the actor model using Akka.NET, the project offers a lot of powerful functionalities. I always try to find new ways for developing software and the actor-model offers me a new paradigm I was not familiar with.

For now I think that this programming model can be very helpful in some situations and I will try to post more on the topic, I really like the project so far!

If you want to learn more about Akka.NET I highly recommend you to try the Petabridge’s bootcamp which will help you to understand the concepts behind the actor model and how they are implemented in Akka. You can find the bootcamp for free here. I also made a presentation a few days ago and you can find the slides here.

See you next time!