Superloopy Logo

Using ScalaTest with Akka

To test Actor code with ScalaTest you have to mix in a lot of traits; sometimes it can be difficult to remember them all. Inspired by a course led by Heiko Seeberger I made this abstract class (it cannot be a trait because it takes constructor parameters) that you can drop into a project.

import akka.actor.ActorSystem
import akka.testkit.{ ImplicitSender, TestKit }
import org.scalatest.{ WordSpec, BeforeAndAfterAll }
import org.scalatest.matchers.MustMatchers

abstract class TestKitSpec(name: String)
    extends TestKit(ActorSystem(name))
    with WordSpec
    with MustMatchers
    with BeforeAndAfterAll
    with ImplicitSender {

  override def afterAll() {
    system.shutdown()
  }
}

You use it like this (extending the test part of my previous post on injecting Akka's TestProbe into actors):

object BarSpec {
  class Wrapper(target: ActorRef)
      extends Actor {
    def receive = {
      case x => target forward x
    }
  }
}

class BarSpec
    extends TestKitSpec("BarSpec") {
  import Bar._
  import BarSpec._

  trait TestCase {
    val probe = TestProbe()
    trait TestChildrenProvider
        extends ChildrenProvider {
      def newBar = new Wrapper(probe.ref)
    }
    val actor = context.actorOf(
      Props(new Bar with TestChildrenProvider))
  }

  "Bar" should {
    "involve child in doing something"
    in new TestCase {
      actor ! "SomeMessage"
      probe.expectMsg("MessageToChild")
      probe.reply("ReplyFromChild")
      expectMsg("ReplyFromParent")
    }
  }
}

I find this makes testing of Akka actors quite nice and clean.

Date: 2013-03-25

Author: Stig Brautaset

Created: 2017-06-19 Mon 12:20

Validate