Testing Akka Actors in Play!

This Article is about Play! 2.1.1 using Scala 2.10.0 - http://playframework.org

I wrote a simple Akka Actor to run some tasks in the background of Play, like a little cron job. This part was somehow good documented and I finished it quite fast. But after that I wanted to write a Test for this actor to check if my task is running. While I wrote already some specs for my Play! application I now came to a new problem for me. How to test async jobs?

The quick and dirty method would be to wait in the test for some seconds till the actor is finished. Bah! I don' t like dirty. Play documentation didn't helped here. So I had to ask google. Somehow this seems to be not a problem for anyone or no body tests his actors.

I found out that Akka has a separate testing unit for exactly this case! So how to use it?

Firstly this testing package is not embedded into Play! and you have to add it to your Build.scala

 

val appDependencies = Seq(
    // Add your project dependencies here,
    jdbc,
    anorm,
    "com.typesafe.akka" % "akka-testkit_2.10.0-RC1" % "2.1.0-RC1"
)

For this to work you need to add the typesafe repository link, this can be done in the plugins.sbt

// The Typesafe repository
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"

If you now run your Play! application it will download the testkit automatically.

Now to the test.

class ActorSpec extends Specification {
    "Actor" should {
        "do something I want to test" in {
            // We need a Fake Application for the Actor system
            val fakeApplication = FakeApplication()
            implicit val system = Akka.system(fakeApplication)
            // Get the TestActor Reference
            val actorRef = TestActorRef[myActor]
            // With this you can access the actor directly, which issn't possible with the normal akka system
            val actor = actorRef.underlyingActor
            // Send a message to the actor
            actor.receive("Ping")
            // This is a synced call, so now you can test your stuff.
            ...
        }
    }
}

We have a synced call here so everything after the actor.receive call, will be after the call is really finished.

This all took me some hours to figure out, so I'm glad to share it to you.

Happy Testing.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.