代码是:
// pilot = Await.result(context.actorSelection(s"../$pilotName").resolveOne, 5.seconds)
pilot = context.actorFor("../" + pilotName)
actorFor在应用和测试中运作良好
评论的代码在应用程序中工作但在运行测试时失败了akka.actor.ActorNotFound
(它看起来存在的演员,我认为超时就足够了),这真的很奇怪。
测试是:
class PilotsSpec extends TestKit(ActorSystem("PilotsSpec",
ConfigFactory.parseString(PilotsSpec.configStr)))
with ImplicitSender with WordSpecLike with MustMatchers {
import PilotsSpec._
import plane.Plane._
def nilActor: ActorRef = TestProbe().ref
val pilotPath = s"/user/TestPilots/$pilotName"
val copilotPath = s"/user/TestPilots/$copilotName"
def pilotsReadyToGo(): ActorRef = {
implicit val timeout = Timeout(5.seconds)
val a = system.actorOf(Props(
new IsolatedStopSupervisor with OneForOneStrategyFactory {
def childrenStart() = {
context.actorOf(Props[FakePilot], pilotName)
context.actorOf(Props(new CoPilot(testActor, nilActor, nilActor)), copilotName)
}
}), "TestPilots")
Await.result(a ? IsolatedLifeCycleSupervisor.WaitForStart, 5.seconds)
system.actorFor(copilotPath) ! Pilots.ReadyToGo
a
}
"CoPilot" should {
"takecontrol when the Pilotdies" in {
pilotsReadyToGo()
// Kill the Pilot
system.actorFor(pilotPath) ! PoisonPill
// Sincethe test classis the "Plane" we can
// expect to see this request
expectMsg(GiveMeControl)
// The girl who sent it had better be Mary
lastSender must be (system.actorFor(copilotPath))
}
}
}
我不知道我是否对ActorSelection做错了
我尝试使用onComplete
但它仍然无法正常工作并在测试中抛出ActorNotFound
异常。
val f = context.actorSelection("../" + pilotName).resolveOne
f onComplete {
case Success(v) => { pilot = v; context.watch(pilot); println("pilot get") }
case Failure(e) => throw e
}
有没有人知道为什么actorFor有效,但是actorSelection失败了(完全在测试中)?
然后我将下面的代码添加到测试代码中:
system.actorSelection(pilotPath).resolveOne map {v => println("------pilot:"+v)}
system.actorSelection(copilotPath).resolveOne map {v => println("------copilot:"+v)}
Thread.sleep(1000)
它工作并打印这些actorRef
然后我尝试将../+pilotName
替换为常量字符串pilotPath
,但它再次失败(无论context.actorSelection
还是context.system.actorSelection
)
这是例外(片段):
仅测试cc.akka.avionics.PilotsSpec
[info]将1个Scala源编译为G:\ scala_workspace \ akka_test_u7 \ target \ scala-2.10 \ test-classes ...
[警告]有2个弃用警告;使用-deprecation重新运行以获取详细信息 [警告]发现一个警告
------副驾驶:演员[阿卡:// PilotsSpec /用户/ TestPilots /玛丽#962346268]
------导频:演员[阿卡:// PilotsSpec /用户/ TestPilots /马克#-320295209]
ActorSelection [锚点(akka:// PilotsSpec / user / TestPilots / Mary#962346268),路径(/../ Mark)]
[ERROR] [04/29/2014 15:13:16.080] [PilotsSpec-akka.actor.default-dispatcher-4] [akka.dispatch.Dispatcher]找不到演员:ActorSelection [Ancho r(akka:// PilotsSpec / user / TestPilots / Mary#962346268),路径(/../ Mark)]
akka.actor.ActorNotFound:未找到Actor:ActorSelection [Anchor(akka:// PilotsSpec / user / TestPilots / Mary#962346268),Path(/../ Mark)]
at akka.actor.ActorSelection $$ anonfun $ resolveOne $ 1.apply(ActorSelection.scala:65)
at akka.actor.ActorSelection $$ anonfun $ resolveOne $ 1.apply(ActorSelection.scala:63)
在scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.processBatch $ 1(BatchingExecutor.scala:67)
at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.apply $ mcV $ sp(BatchingExecutor.scala:82)
at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.apply(BatchingExecutor.scala:59)
at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.apply(BatchingExecutor.scala:59)
在scala.concurrent.BlockContext $ .withBlockContext(BlockContext.scala:72)
at akka.dispatch.BatchingExecutor $ Batch.run(BatchingExecutor.scala:58)
at akka.dispatch.ExecutionContexts $ sameThreadExecutionContext $ .unbatchedExecute(Future.scala:74)
at akka.dispatch.BatchingExecutor $ class.execute(BatchingExecutor.scala:110)
只有actorFor在测试中使用actorSelection
注释的其他代码在应用程序中起作用但在测试中失败(很奇怪):
class CoPilot(plane: ActorRef,
var controls: ActorRef,
altimeter: ActorRef) extends Actor {
implicit val timeout = Timeout(1.second)
implicit val ct = context.dispatcher
var pilot: ActorRef = context.system.deadLetters
val pilotName: String = context.system.settings.config.getString("cc.akka.avionics.flightcrew.pilotName")
val pilotId : Int = 200
def receive = {
case ReadyToGo =>
// fails in test
// pilot = Await.result(context.actorSelection(s"../$pilotName").resolveOne, 3.seconds)
// println("get pilot:" + pilot.path + " dead:" + pilot.isTerminated)
// actorFor works
// pilot = context.actorFor("../" + pilotName)
// context.watch(pilot)
// autopilot = Await.result(context.actorSelection("../AutoPilot").resolveOne, 100.millis)
// fails in test
// val f = context.actorSelection("../" + pilotName).resolveOne
// f onComplete {
// case Success(v) => { pilot = v; context.watch(pilot); println("pilot get") }
// case Failure(e) => throw e
// }
println("-----------"+pilotName)
// fails in test
context.actorSelection("../" + pilotName) ! Identify(pilotId)
case Terminated(_) =>
plane ! GiveMeControl
case Controls(controlSurfaces) =>
controls = controlSurfaces
case ActorIdentity(pilotId, Some(ref)) =>
pilot = ref
context.watch(pilot)
println("find copilot:"+pilot)
case ActorIdentity(pilotId, None) =>
println("failed to find pilot")
}
}