【问题标题】:Akka JavaTestKit JUnit Message not sent to default/userAkka JavaTestKit JUnit 消息未发送到默认/用户
【发布时间】:2013-10-01 18:17:21
【问题描述】:

我正在使用 JavaTestKit 编写 Akka JUnit 测试,并试图找出我做错了什么。

我有一个 AkkaSystem,我用它来创建一个 Inbox 对象并向 ExecutiveSupervisor 发送消息。

ActorSystem akkaSystem = ActorSystem.create("myAkkaSystem");

Props executiveProps = Props.create(ExecutiveSupervisor.class);
TestActorRef<ExecutiveSupervisor> executiveSupervisorTestActorRef = TestActorRef.create(akkaSystem, executiveProps, "testExecutiveSupervisor");

new JavaTestKit(akkaSystem) {{

    final Inbox inbox = Inbox.create(akkaSystem);
    inbox.send(executiveSupervisorTestActorRef, new Object());
    ResultAndData result = (Object)inbox.receive(Duration.create(2, TimeUnit.SECONDS));

 }};

ResultAndData 对象被传递到作为 UnTypedActor 的 ExecutiveSupervisor 类中,并且当我在调试时查看它时正确接收。

执行非常愉快地通过actor中的代码。 在工作人员的某个点上,我希望它在 ActorSystem 级别的测试中将其传递的相同对象(ResultAndData)返回到 JUnit 的收件箱。 IE。我希望工人将其传递的同一对象返回给其父对象。

但是,正如它试图返回以下行一样:

log.info("SUCCESS!!!!!!!!!!!");
getContext().parent().tell(result, getSelf());  //FAILS HERE

此时我收到此消息:

[INFO] [09/30/2013 19:22:38.609] [default-akka.actor.default-dispatcher-4] [akka://default/user] 消息 [com.netaporter.modules.serviceagent.从 TestActor[akka://default/user/testExecutiveSupervisor] 到 Actor[akka://default/user] 的 remoteservices.ResultAndData] 未交付。 [1] 遇到死信。可以使用配置设置“akka.log-dead-letters”和“akka.log-dead-letters-during-shutdown”关闭或调整此日志记录。

基本上,该消息准确地描述了我想要发生的事情,但事实并非如此。 我想要一个从 testExecutiveSupervisor 返回到其父默认/用户的 ResultAndData 对象。

如果我在 JUnit 中加入一行:

expectMsgEquals(duration("2 seconds"), result);

“结果”是我的 ResultAndData 对象,它总是会超时,因为消息没有通过。

谢谢大家,任何帮助都会很棒。

【问题讨论】:

    标签: java junit akka actor


    【解决方案1】:

    你应该像这样返回消息:

    sender().tell(result, getSelf());
    

    现在你正在向你的actor的父级发送消息,因为你的actor是顶级actor,这不会成功。你的演员的父母不是收件箱,所以你正在尝试的事情不会成功。父级是在其上下文中创建子级的 Actor,当您通过 ActorSystem 上的 TestActorRef 创建 Actor 时,它将是以默认/用户 Actor 作为父级的顶级 Actor,您不能将其用于接收消息。 我怀疑您真正想要的是回复消息,因此您应该将消息发送给当前消息的发件人,您可以使用sender() 检索。

    【讨论】:

    • 我有一个问题,ExecutiveSupervisor 工作人员也会触发童工。他们返回ExecutiveSupervisor,返回ResultAndData,如果我要在代码中写:sender().tell(result, getSelf());,而不是实际代码本身中的getContext().parent().tell(result, getSelf());,它会将消息返回给它的孩子。 IE。如果它是 JUnit,getSender() 调用很好,但如果它正常运行,它将向错误的方向发送消息。
    • 你可以直接使用worker.forward(message)将消息从supervisor发送给worker,然后worker可以直接回复sender。 Forward 保留了消息的原始发送者,非常适合此类场景。
    猜你喜欢
    • 2013-04-30
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    • 2014-12-03
    • 2012-11-12
    • 2012-10-09
    • 2023-03-17
    • 2022-01-13
    相关资源
    最近更新 更多