我想测试以下情形:
假设我有一个父的演员,这创建了两个儿童演员这个样子。
class A extends Actor {
def getActorOf(props: Props) = {
context.actorOf(props, props.clazz.getTypeName)
}
def receive: Receive = {
case "ping" => {
val bChild = getActorOf(Props[B])
val cChild = getActorOf(Props[C])
Seq(bChild, cChild)
.foreach(child => child ! "ping forwarded")
}
}
}
我想测试,如果在情况下,父亲让'ping'
他会送“ping forwarded'
消息到两个自己的孩子。
是否有可能与TestKit做到这一点?
像这样的事情,也许?
class TestMe extends A {
val (probeB, probeC) = (TestProbe(), TestProbe())
override def getActorOf(props: Props) = props match {
case Props(_, classOf[B], _) => probeB.ref
case Props(_, classOf[C], _) => probeC.ref
}
}
val fixture = TestActorRef[TestMe](Props[TestMe])
fixture ! "ping"
fixture.underlyingActor.probeB.expectMsg("ping forwarded")
fixture.underlyingActor.probeB.expectMsg("ping forwarded")
就个人而言,我更喜欢一个更“传统”的方式,只要有可能:
trait Forwarder {
def startAndForward[T : ClassTag](message: Any)(implicit context: ActorContext) = {
val actor = context.actorOf(Props[T])
actor ! message
actor
}
}
object Forwarder extends Forwarder
class A(f: Forwarder = Forwarder) extends Actor {
def receive: Receive = {
case m@"ping" =>
f.startAndForward[B]("ping forwarded")
f.startAndForward[C]("ping forwarded")
sender ! "pong"
}
}
现在,你可以运行简单的方法测试:
val fwd = mock[Forwarder]
val fixture = context.actorOf(Props(new A(fwd)))
fixture.ask("ping").futureValue shouldBe "pong"
verify(fwd).startAndForward[B](ArgumentMatchers.eq("ping forwarded"))(any, any)
verify(fwd).startAndForward[C](ArgumentMatchers.eq("ping forwarded"))(any, any)