Akka : Testing your Actors

Introduction

Akka is a great Scala and Java framework implementing the “Actor” programming model. It allows developers to easily build concurrent systems.

The main ideas behind the Actor model are:

  • The work is divided into small tasks
  • An Actor is responsible for executing one task
  • Actors communicate between each other asynchronously by sending messages

Akka takes care of the Actors lifecycle, execution scheduling and communication.

The only possible interactions with an Actor are sending messages and receiving back other messages. As the actor’s execution is made asynchronously, it can be hard to test without proper tools. Fortunately, Akka comes with a set of testing tools, the “TestKit”, that come handy when dealing with actors testing.

TestKit library

To use the Akka Testkit, you just have to add a dependency on it (usually for the “test” scope). In a classical SBT configuration, it should look as follow :

libraryDependencies += "com.typesafe.akka" %% "akka-testkit" % "2.1.4" % "test"

After reloading the SBT configuration, all the TestKit tools should be available in your project.

The TestKit class

One of the main tool provided by Akka Testkit is the TestKit class. Your test class can extend it and provide an ActorSystem and this system will be available implicitely in all your test cases. Note that you can also use the TestKitBase trait if you need a trait instead of a class.

class BasicTest extends TestKit(ActorSystem("testSystem"))
  with WordSpec
  with MustMatchers {
  ...
}

This implicit Akka System will be used by the other Testkit tools and will allow to keep your code as simple as possible.

The TestActorRef class

The asynchronous model using by Akka can make it difficult to test. One can quickly have to do some complicated code with waits, timeouts,…

Fortunately, Akka Testkit comes with the TestActorRef class.

When you create an Actor with the TestActorRef, it will use a special message dispatcher called CallingThreadDispatcher that will execute the actor receive() method in the same thread it has been sent. Therefore, all your tell() calls will become synchronous and more easily testable.

In addition to making the actor message processing synchronous, the TestActorRef will give back a special ActorRef instance that allows you to access the underlying actor instance (which is not possible with standard Akka actors). It allows you to make assertions about some of the actor’s internal states.

Here is a sample code showing this usage :

The ImplicitSender trait

If you want to test an actor by sending him a message and expecting that it has replied to the sender, you can use the ImplicitSender trait. This trait will define an implicit ActorRef to a fake Actor and this ActorRef will be used automatically as the sender when you use the tell() (or !) method.

You can then use the expectMsg…() method available through the TestKit class to check wheter this fake actor has received any message.

The TestKit class provide a lot of different variants of the expectMsg…() method : expectMsgClass(), expectMsgAnyOf(), expectMsgAllOf(), expectNoMsg(),…

To be continued

We went through the basic mechanisms provided by Akka Testkit to allow easy testing of your actors. You can find additional information on the section dedicated to testing in the Akka Documentation.

Next time, we will go through more advanced actors testing techniques with the use of TestProbe and AutoPilot.

Développement web , , ,

7 comments


  1. Not myname

    DO IT IN JAVA

  2. akanksha singh

    thankyou for explaining in clear and simple terms !!

  3. galway

    Really nice tutorial on testkit

  4. Xu Cheng

    If the Actor requires Props, how to create it using TestActorRef? Thanks.

  5. Very good post, thanks.

  6. Khalian

    Your shitty examples dont work. Compilation failures galore (and this after sbt dependency res). Get your shit together

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>