There are several approaches you can take in order to mock the Child actor. One of them is to externalize code for child creation from parent actor.
In order to do it, you need to rewrite your Parent actor and pass it a function that will create your Child actor:
Note: we will use AbstractActor instead of UntypedActor due to deprecation in version 2.5.0.
public class Parent extends AbstractActor {
private final ActorRef child;
public Parent(Function<ActorRefFactory, ActorRef> childCreator) {
this.child = childCreator.apply(getContext());
}
public static Props props(Function<ActorRefFactory, ActorRef> childCreator) {
return Props.create(Parent.class, childCreator);
}
@Override
public Receive createReceive() {
return receiveBuilder()
.matchEquals("send ping", s -> child.tell("ping", getSelf()))
.match(String.class, System.out::println)
.build();
}
}
Your Child actor will stay the same:
public class Child extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.matchEquals("ping", s -> getSender().tell("pong", getSelf()))
.build();
}
}
Now in your test you can use probe actor reference to test the message that should be sent to Child actor i.e. probe will act as Child actor mock:
public class ParentTest {
static ActorSystem system;
@BeforeClass
public static void setUpClass() {
system = ActorSystem.create();
}
@AfterClass
public static void tearDownClass() {
TestKit.shutdownActorSystem(system);
system = null;
}
@Test
public void givenParent_whenSendPing_thenPingChild() {
TestKit probe = new TestKit(system);
Function<ActorRefFactory, ActorRef> childCreator = arf -> probe.getRef();
ActorRef parentActor = system.actorOf(Parent.props(childCreator));
probe.send(parentActor, "send ping");
probe.expectMsgEquals("ping");
}
}
So, instead of using (would be used in real application code):
Function<ActorRefFactory, ActorRef> childCreator = arf -> arf
.actorOf(Props.create(Child.class));
we are going to use:
Function<ActorRefFactory, ActorRef> childCreator = arf -> probe.getRef();
and check if probe received a "ping" message.
Hope it helps. More info about given approach can be found here.