I previously blogged about testing messages sent back to the sender. Another common scenario is testing that an actor sends the correct message to a child. A piece of code that does this might look like:
But how do you test drive this kind of code?
I've adopted the approach of removing the responsibility of creating the child from the ParentActor. To do this you can pass in a factory to the ParentActor's constructor that can be replaced for testing. To do this the ParentActor is changed to look like this:
The ParentActor now takes in a factory function which takes in an ActorFactoryRef and returns a ActorRef. This function is responsible for creating the ChildActor.
childFactory: (ActorRefFactory) => ActorRef
This is then used by the ParentActor as follows:
val childActor = childFactory(context)
You can now inject a TestProbe for testing rather than using a real ActorFactorRef. For example:
And for the real code you can pass in an anonymous function that uses the ActorRefFactory to actually create a real ChildActor:
Here you can see the ActorFactoryRef (context in Actors implement this interface) is used to create an Actor the same way as the original ParentActor did.
Full source code here.
1 comment:
Hi, nice job with this scenario. I have a question about parent actor: you can easily create an actor with "new", but how to create a parent actor ref? With actor instance I cannot use ! method.
Thanks
Post a Comment