0
votes

In an asynchronous (typed) actor test I have to make sure that a specific message has been received by an actor before I send the next one. This is necessary because messages can reach the actor under test via several child actors (when sending the message directly the order would be guaranteed anyway).

Since the actor might only change its internal state and not signal to the outside world that the message has been received, I have to find another way to wait until the message is processed.

Is there a way to wait until all inboxes are empty? I think that ManualTime.timePasses(0.seconds) could do the job but I'm not sure and it slows down my tests considerably. Obviously I don't want to use Thread.sleep(...) because it doesn't really guarantee that all messages are processed and the tests would be even slower.

I also tried using a BehaviorInterceptor to figure out when the main actor has received a message but this is only possible when I know which messages the child actors send to the main actor. This should actually be transparent in the test so I'm looking for a generic way to assert that the actors are done with processing messages (since I control the scheduler, no timer messages are generated).

1

1 Answers

0
votes

I found out this is actually pretty easy to accomplish: A CallingThreadDispatcher processes all actor messages immediately and delivery and processing of messages is deterministic. It is never necessary to wait for messages to process because they are processed in the test thread before the tell (or !) call returns.

You can configure it for your test actor system like this in Akka Typed:

val config = ConfigFactory.parseString(
    """akka.actor.default-dispatcher =
        { type = akka.testkit.CallingThreadDispatcherConfigurator }"""
)

val testKit = ActorTestKit(ActorTestKitBase.testNameFromCallStack(), config)