当前位置: 首页 > 知识库问答 >
问题:

如何测试Actor Foo将消息发送到新创建的子演员栏?

胡博艺
2023-03-14

我有一个演员foActor,它传递了Props来实例化几个BarActor,并向它发送BarMessage。代码可以工作,但是我很难为它编写测试。添加的限制是,我只能在这个应用程序中使用Java代码,没有Scala代码。

经过几次尝试,这似乎是我迄今为止最大的努力:

@Test
public void testJavaTestKit() {

    new JavaTestKit(system) {{
        JavaTestKit probe = new JavaTestKit(system);

        // pretending that the probe is the receiving Bar, by returning it in the Props
        Props barActorProps = Props.create(BarActor.class, new Creator() {
            @Override
            public Object create() {
                return probe.getRef();
            }
        });
        Props props = Props.create(FooActor.class, barActorProps);
        ActorRef subject = system.actorOf(props);

        Object msg = // basically irrelevant, will trigger Bar instantiation and message sending

        subject.tell(msg, probe.getRef());

        expectMsgClass(Bar.BarMessage.class);
        expectNoMsg();
    }};
}

这一切对我来说似乎都有意义,但即使我可以看到消息被发送到新创建的Bar实例,第一个断言还是失败了。我做错了什么?

更新:

与Akka留档示例不同的是,我不想传递接收消息的现有参与者。相反,我想传递用于创建子角色实例的Props。在测试中,我希望我的探测接收到新创建的参与者的消息。这就是为什么我添加了Props.create构造,它应该始终返回相同的探测参与者。刚才我在Creator.createAPI中看到这个注释:

方法必须在每次调用时返回不同的实例。

所以这显然行不通,因为这正是我想要的。因此,我的一般问题仍然是:如何测试发送给新创建的子角色的消息?

共有2个答案

萧永长
2023-03-14

我认为这样的事情应该适合你的情况。

class ActorSpec extends Specification {
    @Shared
    private ActorSystem system
    @Shared
    private ActorRef actorRef
   def setupSpec() {
        system = ActorSystem.create("test-system",ConfigFactory.load("application.conf"))
    }
   def "Verify message received"() {
     given:
            JavaTestKit probe = new JavaTestKit(system)
            final Props props = Props.create(BarActor.class)
            actorRef = system.actorOf(props)
        when:
            actorRef.tell(new BarMessage(), probe.getRef())
        then:
            probe.expectMsgClass(Bar.BarMessage.class);
    }
 def cleanupSpec() {
        JavaTestKit.shutdownActorSystem(system)
        system = null
    }
戈博易
2023-03-14

您试图欺骗如何初始化子角色(通过传递probeRef)以灵活地测试它们,但问题是偶数Creator是通用的,用于标准上下文getContext(). actorOf(),不能返回ActorRef作为创建方法的结果。合同需要始终遵循Creator

请看一下ActorCreationTest

我可能是错的,因为我不知道您的FooActor是如何实现的,但是如果您将使用标准模式getContext()。actorOf()default AkkaAkka。男演员创建者消费者将不接受您的消费者

caused by: java.lang.ClassCastException: akka.actor.RepointableActorRef cannot be cast to akka.actor.Actor
    at akka.actor.CreatorConsumer.produce(Props.scala:335)
    at akka.actor.Props.newActor(Props.scala:252)
    at akka.actor.ActorCell.newActor(ActorCell.scala:552)
    at akka.actor.ActorCell.create(ActorCell.scala:578)
    ... 9 more

您可以尝试返回匿名转发,而不是返回ActorRef来探测?

import akka.actor.*;
import akka.japi.Creator;
import akka.testkit.JavaTestKit;
import org.junit.Test;

public class ActorTest {

    @Test
    public void testJavaTestKit() {
        ActorSystem system = ActorSystem.create("Acceptor");

        new JavaTestKit(system) {{
            JavaTestKit probe = new JavaTestKit(system);

            Creator creator = () -> new UntypedActor() {
              @Override
              public void onReceive(Object message) throws Exception {
                  probe.getRef().tell(message, sender());
              }
            };


            ActorRef subject = system.actorOf(Props.create(FooActor.class, creator));

            subject.tell(new Bar().new BarMessage(), probe.getRef());
            probe.expectMsgClass(Bar.BarMessage.class);


        }};
    }

}


class BarActor extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {

    }
}

class FooActor extends UntypedActor {

    ActorRef barRef;

    public static Props props(final Creator creator) {
        return Props.create(FooActor.class, () -> new FooActor(creator));
    }
    public FooActor(Creator creator) {
        barRef = getContext().actorOf(Props.create(creator),"bar");
    }

    @Override
    public void onReceive(Object message) throws Exception {
        barRef.tell(message,sender());
    }
}

class Bar {
    class BarMessage {

    }
}

 类似资料:
  • 我觉得我遗漏了一些显而易见的东西,但是如何在我的内部测试版本中向我的测试人员推送更新呢?我没有看到像我在初始版本(1.0.0)中那样上传新应用包的方法。

  • 问题内容: python的日志记录模块是否有一种简单的方法可以将具有DEBUG或INFO级别的消息以及具有更高级别的消息发送到不同的流? 反正这是个好主意吗? 问题答案: 不一定是一个好主意(将信息和调试消息混入正常输出中可能会造成混淆!),但可行,因为您可以有多个处理程序对象和每个对象的自定义过滤器,以便选择日志记录每个处理程序要处理的内容。

  • 我正在使用avro生成一个java类(Heartbeat),我正在使用Spring云消息处理器,以便使用这个Heartbeat类将消息推送到kafka。 以下是我的服务: 我的测试包中有一个消费者: 现在在我的实际测试课上,我有这个: 我可以通过运行ksql看到消息确实到达kafka。所以消息正如预期的那样在那里。我也收到了来自我的心跳Kafka消费者的消息,但当我做断言时,我收到了这个错误: 现

  • 我正在尝试为Web设置Firebase云消息传递。我成功地对其进行了正确初始化并获得了令牌: manifest.json与gcm_sender_id 我可以看到我在控制台中得到令牌,所以我试图验证它,并通过邮递员发送我的第一个通知-这里是留档。 发布网址:https://fcm.googleapis.com/v1/projects/PROJECTID/messages:发送授权:无授权 标题 Bo

  • 问题内容: 我想使用Java将“推送通知”消息发送到特定的iPhone设备。 我不知道该怎么做。 我对此进行了谷歌搜索,他们建议使用“ PayLoad”类,但不要从任何jar文件中获取此类。 请有人指导我通过Java将推送通知消息发送到iPhone吗? 问题答案: 使用JavaPNS。例如:

  • 这就是我所拥有的: 我需要机器人在加入时发送一条包含规则和命令列表的私人消息。 请帮忙!