我有一个actor FooActor被传递Props来实例化几个BarActors并发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();
}};
}
Run Code Online (Sandbox Code Playgroud)
这一切对我来说似乎都有意义,但即使我可以看到消息被发送到新创建的Bar实例,第一个断言也会失败.我究竟做错了什么?
更新:
使其与Akka文档示例不同的是,我不想传递接收消息的现有actor.相反,我想传递Props用于创建子actor实例的那个.在测试中,我希望我probe接收到新创建的actor的消息.这就是我添加Props.create应该始终返回相同探测器的构造的原因.刚才我在Creator.createAPI中看到了这条评论:
此方法必须在每次调用时返回不同的实例.
所以这显然不会起作用,因为它正是我想要的.所以我的一般问题仍然是:如何测试发送给新创建的子actor的消息?
您试图“欺骗”子演员的初始化方式(通过传递probeRef),以便灵活地测试它们,但问题是,即使Creator是通用的,在标准上下文中使用getContext().actorOf(),也不能ActorRef作为该create方法的结果返回。合同需要始终如下Creator<T extends Actor>。
我可能是错的,因为我不知道你的FooActor是如何实现的,但如果你使用标准模式,getContext().actorOf()默认 Akkaakka.actor.CreatorConsumer将不会接受你的Consumer.
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
Run Code Online (Sandbox Code Playgroud)
您可以尝试返回匿名转发器,而不是返回ActorRef探测Actor?
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 {
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1509 次 |
| 最近记录: |