While writing some Akka code I eventually got to a point where I needed to test that a child actor received a message from the actor I am testing, which I will call Manuel in this post.

We test this by injecting a TestProbe actor, provided by akka-testkit, into Manuel. We can do this injecting this probe as a dependency in the Manuel constructor.

The problem with this simple approach is that it will probably break your actor hierarchy. In my case I wanted Manuel to supervise its children, so I need to create these children in Manuel's actor context. If these children are injected in the constructor, then Manuel will not supervise them, because they are not actually its children. The actor that created Manuel would supervise them.

The easy way I found to do this is very java influenced, but it works and it is very simple and readable.

We just need to define a factory method on Manuel and then override this method in the test so that it returns a TestProbe instead of a real child. Then you can inspect the messages sent to the probe.

For example:

class Manuel extends Actor {
  import context.system
  val log = Logging(context.system, this)

  lazy val child = system.actorOf(Props[Child])

  def receive: Receive = {
    case m =>
        log.debug("Received a new message, notifying my child")
        child ! 'world
  }
}

And the test:

class ManuelTest extends TestKit(ActorSystem("testSystem")) with FunSuiteLike {
  test("the child receives a message") {
    val probe = TestProbe()

    val manuel = system.actorOf(Props(new Manuel {
      override lazy val child = probe.ref
    }))

    receiver ! 'hi

    probe.expectMsg('world)
  }
}

This way you can easily test the messages Manuel sends to its children.

If you need more to do have some more complex tests you can read more about the different ways around this problem in this post.



comments powered by Disqus