I am trying to write unit test for one of my actors which is derived from AbstractPersistentActorWithAtLeastOnceDelivery using TestKit. I need to create an actor with TestActorRef.create(...) since I need to get an underlyingActor in order to inject the mocks into actor's implementation.
My (simplified) actor
public class MyActor extends AbstractPersistentActorWithAtLeastOnceDelivery {
@Override
public Receive createReceive() {
return receiveBuilder().match(String.class, message -> {
persist(new MessageSent(message), event -> updateState(event));
}).match(ConfirmMessage.class, confirm -> {
persist(new MessageConfirmed(confirm.deliveryId), event ->
updateState(event));
}).matchAny(message -> log.info("Received unexpected message of class {}.
Content: {}", message.getClass().getName(), message.toString())).build();
}
void updateState(Object received) {
if (received instanceof MessageSent) {
final MessageSent messageSent = (MessageSent) received;
ActorRef destinationActor =
findDestinationActor(messageSent.messageData);
deliver(actorSystem.actorSelection(destinationActor.path()),
deliveryId -> new Message(deliveryId, messageSent.messageData));
} else if (received instanceof MessageConfirmed) {
final MessageConfirmed messageConfirmed = (MessageConfirmed) received;
confirmDelivery(messageConfirmed.deliveryId);
}
}
Unit test:
@Test
public void actorTest() {
ActorSystem system = ActorSystem.create();
TestKit probe = new TestKit(system);
TestActorRef<myActor> testActor = TestActorRef.create(system, props,
probe.getRef());
MyActor myActor = testActor.underlyingActor();
injectMocks(myActor); // my method
testActor.tell("testMessage", probe.getRef());
List<Object> receivedMessages = probe.receiveN(1, FiniteDuration.create(3,
TimeUnit.SECONDS));
}
In debugger I see that deliver() method inside updateState() is called, but the unit test fails with error:
assertion failed: timeout (3 seconds) while expecting 1 messages (got 0)
I am wondering if it is possible at to use the TestKit to test an actor created via TestActorRef and if the fact that my actor extends AbstractPersistentActorWithAtLeastOnceDelivery has something to do with tests failure