如何确保Akka演员活着并订阅了事件流

时间:2016-12-09 10:54:38

标签: java unit-testing akka

我正试图在java中测试一个Akka Actor。这是测试试图做的,代码在

之下
  • 这个被测试的演员在他的构造函数中订阅了evenstream。
  • 使用actor系统上的普通actorOf在测试中创建actor。
  • 这会返回一个ActorRef,然而真正的角色是在幕后异步创建的。
  • 我在测试中在事件流上发布了一条消息。
  • 但是,由于actor是异步构造的,因此在actor将自己订阅到事件流之前,会在事件流上发布消息。
  • 结果:被测试的演员从未看到该消息,并且神经元将其转发给他应该将消息转发给的演员。测试失败,因为要转发的actor是我们期望消息到达的测试中的testprobe。

在将消息发布到事件流之前,我可以睡觉或等待片刻,但是没有“更清洁”的方法来检查演员是否完全启动并运行?我可以在事件流上听一些事件,告诉我演员已经完成了自己的创作吗?

@Test
public void testListenOnEventStreamAndForward() throws InterruptedException
{
    // given
    final TestProbe actorToForwardMessageTo = new TestProbe(this.actorSystem);
    final Function<ActorRefFactory, ActorRef> actorToForwardMessageTosFactoryFunction = (actorRefFactory) -> actorToForwardMessageTo.ref();
    this.actorSystem.actorOf(Props.create(ActorUnderTest.class, () -> new ActorUnderTest(actorToForwardMessageTosFactoryFunction)));

    //The test is green, depending on the whether we sleep here or not
    //Thread.sleep(1000);

    // when
    this.eventStream.publish("someStringMessageTheActorUnderTestShouldPickUp");

    // then
    actorToForwardMessageTo.expectMsg("someStringMessageTheActorUnderTestShouldPickUp");
}


private static class ActorUnderTest extends AbstractActor
{

    public ActorUnderTest(final Function<ActorRefFactory, ActorRef> actorToForwardMessageToFactoryFunction) throws Exception
    {
        context().system().eventStream().subscribe(self(), String.class);
        final ActorRef actorToForwardMessageTo = actorToForwardMessageToFactoryFunction.apply(getContext());

        receive(ReceiveBuilder
                .match(
                        String.class,
                        stringMessage -> actorToForwardMessageTo.tell(stringMessage, self()))
                .matchAny(
                        message -> unhandled(message))
                .build());
    }

}

1 个答案:

答案 0 :(得分:0)

您可以使用awaitAssert重试发布/预期消息,直到超时才会失败。请参阅此处文档中的awaitAssert部分:http://doc.akka.io/docs/akka/2.4/java/testing.html