如何等待所有参与者在测试中处理他们的收件箱

How to wait for all actors to process their inboxes in a test

在异步(类型化)actor 测试中,我必须确保在发送下一条消息之前,actor 已收到特定消息。这是必要的,因为消息可以通过多个子 actor 到达被测 actor(当直接发送消息时,顺序无论如何都会得到保证)。

由于 actor 可能只会改变其内部状态,而不会向外界发出消息已收到的信号,因此我必须找到另一种方法来等待消息被处理。

有没有办法等到所有收件箱都清空?我认为 ManualTime.timePasses(0.seconds) 可以完成这项工作,但我不确定,它大大减慢了我的测试速度。显然我不想使用 Thread.sleep(...) 因为它并不能真正保证所有的消息都被处理并且测试会更慢。

我还尝试使用 BehaviorInterceptor 来确定主要演员何时收到消息,但这只有在我知道子演员向主要演员发送了哪些消息时才有可能。这在测试中实际上应该是透明的,所以我正在寻找一种通用方法来断言参与者已完成处理消息(因为我控制调度程序,所以不会生成计时器消息)。

我发现这实际上很容易实现:CallingThreadDispatcher 立即处理所有参与者消息,消息的传递和处理是确定的。永远不需要等待消息处理,因为它们在 tell(或 !)调用 returns 之前在测试线程中处理。

您可以在 Akka Typed 中像这样为您的测试 actor 系统配置它:

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

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