我有一个演员,从启动器接收消息,然后询问工作人员,最后将结果发送给启动器。
在代码中更清楚:
public class MyActor extends UntypedActor {
private final ActorRef worker;
public MyActor(ActorRef worker) {
this.worker = worker;
}
@Override
public void onReceive(Object message) throws Exception {
if ("initiate".equals(message)) {
final ActorRef initiator = sender();
final Future f = Patterns.ask(worker, "ask:"+message, Timeout.apply(3, TimeUnit.SECONDS));
Patterns.pipe(f, context().system().dispatcher()).to(initiator);
}
}
}
现在尝试测试该演员。
我需要测试的内容(如果我错了,请纠正我):
1)当收到“发起”时,工作人员应收到“询问:发起”
2)当收到“响应”时,发起人应收到“响应工作”
并测试:
@Test
public void testIt() {
new JavaTestKit(system) {
{
JavaTestKit initiator = new JavaTestKit(system);
JavaTestKit worker = new JavaTestKit(system);
final Props props = Props.create(MyActor.class, worker.getRef());
final ActorRef subject = system.actorOf(props);
subject.tell("initiate", initiator.getRef());
worker.expectMsgEquals("ask:initiate");
subject.tell("responseFromWorker", worker.getRef());
//this fails
initiator.expectMsgEquals("responseFromWorker");
}
};
}
升级
发起方未收到消息:
java.lang.AssertionError: assertion failed: timeout (3 seconds) during expectMsg while waiting for responseFromWorker
尽管我的演员代码正确:
static class Worker extends UntypedActor {
@Override
public void onReceive(Object message) throws Throwable {
if (message.equals("ask:initiate"))
sender().tell("responseFromWorker", self());
}
}
static class Initiator extends UntypedActor {
@Override
public void onReceive(Object message) throws Throwable {
if (message.equals("responseFromWorker"))
System.out.println("Initiator receive responseFromWorker");
}
}
@Test
public void noAkkaTestKit() {
final ActorRef worker = system.actorOf(Props.create(Worker.class));
final ActorRef initiator = system.actorOf(Props.create(Initiator.class));
final ActorRef subject = system.actorOf(Props.create(MyActor.class, worker));
subject.tell("initiate", initiator);
}
所以我做错了。如何正确测试JavaTestKit
?
因为Ask Future模式将创建一个新的actor来接收响应msg,所以代码
subject.tell("responseFromWorker", worker.getRef());
会将消息直接发送给主题,而不是该参与者。
您可以将msg发送到测试探针的最后一个msg发送者
我写了一个scala版本
import java.util.concurrent.TimeUnit
import akka.actor.{Props, Actor, ActorRef, ActorSystem}
import akka.pattern.{ask, pipe}
import akka.testkit.{TestProbe, ImplicitSender, TestKit}
import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach, Matchers, WordSpecLike}
class MyActor(worker: ActorRef) extends Actor {
import context.dispatcher
override def receive: Receive = {
case message@"initiate" =>
val initiator = sender()
println("received " + message)
val f = ask(worker, "ask:" + message)(akka.util.Timeout(3, TimeUnit.SECONDS))
f pipeTo initiator
case msg =>
println(msg)
}
}
class ActorSpec extends TestKit(ActorSystem("MySpec"))
with ImplicitSender with WordSpecLike with BeforeAndAfterAll with BeforeAndAfterEach with Matchers {
val workerProbe = TestProbe()
val initiatorProbe = TestProbe()
val props = Props(new MyActor(workerProbe.ref))
val subject = system.actorOf(props)
subject.tell("initiate", initiatorProbe.ref)
workerProbe.expectMsg("ask:initiate")
workerProbe.sender.tell("responseFromWorker", workerProbe.ref)
initiatorProbe.expectMsg("responseFromWorker")
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句