sean_robbins sean_robbins - 1 month ago 18
Scala Question

How to mock child Actors for testing an Akka system?

When I have a parent actor in Akka, that directly creates a child actor on initialisation, when I want to write unit tests for the parent actor, how can I replace the child actor with a TestProbe or a mock?

For example, with the following contrived code sample:

class TopActor extends Actor {
val anotherActor = context.actorOf(AnotherActor.props, "anotherActor")

override def receive: Receive = {
case "call another actor" => anotherActor ! "hello"
}
}

class AnotherActor extends Actor {

override def recieve: Receive = {
case "hello" => // do some stuff
}

}


If I want to write a test for TopActor, to check the message sent to AnotherActor is "hello", how do I replace the implementation of AnotherActor? It seems like TopActor creates this child directly so this is not easy to access.

Answer

The following approach seems to work but overriding the val of anotherActor directly seems a little crude. I was wondering if there were any other cleaner/ recommended solutions, which is why I still asked the question even though I have this working answer:

class TopActorSpec extends MyActorTestSuiteTrait {
  it should "say hello to AnotherActor when receive 'call another actor'" {
    val testProbe = TestProbe()

    val testTopActor = TestActorRef(Props(new TopActor {
      override val anotherActor = testProbe.ref
    }))

    testTopActor ! "call another actor"
    testProbe.expectMsg(500 millis, "hello")
  }
}