代码为:
// 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))
}
}
}
我不知道我是否做错了演员选择。
我尝试使用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)
然后我尝试用常量字符串pilotPath
替换../+pilotName
,但再次失败(无论是context.actorSelection
还是context.system.actorSelection
)
下面是例外(一个片段):
航空电子设备飞行员规范
[详细信息]正在将1个Scala源代码编译为G:\scala_workspace\akka_test_u7\target\scala-2.10\测试类...
[warn]有2个不推荐使用警告;有关详细信息,请使用-deprecation重新运行
[警告]找到一个警告
------副驾驶:演员[akka://驾驶员规格/用户/测试驾驶员/玛丽#962346268]
------飞行员:参与者[akka://飞行员规范/用户/测试飞行员/Mark#-320295209]
参与者选择[锚(akka://试点规范/用户/测试试点/Mary#962346268),路径(/../Mark)]
[错误] [04/29/2014 15:13:16.080] [PilotsSpec-akka.actor.default-dispatcher-4] [akka. dispatcher.Dispatcher]未找到以下项的执行元:演员选择[Ancho r(akka://试点规范/用户/测试试点/玛丽#962346268),路径(/../Mark)]
akka.actor.ActorNotFound:找不到以下项目的执行元:参与者选择[锚(akka://试点规范/用户/测试试点/Mary#962346268),路径(/../Mark)]
在akka. actor. actorselection中,选择一个角色,然后应用这个角色。
请输入您的姓名和密码,然后输入您的密码。
在scala.concurrent.impl.CallbackRunnable.run(承诺。等级:32)
在akka.dispatch.batchingExecutor$Batch$$anonfun$run$1.processBatch$1(批处理执行程序.比例:67)
在akka.dispatch.batchingExecutor$Batch$$anonfun$run$1.apply$mcV$sp(批处理执行程序.比例:82)上执行批处理。
(批处理执行程序.规模:59)
(批处理执行程序.规模:59)
在scala中创建一个新的块上下文。
(Batch.run批量执行程序,规模:58)
(未来的脚本:74)
在这个例子中,您可以使用一个脚本来执行批处理操作。
只有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")
}
}
1条答案
按热度按时间q3aa05251#
actorFor会建立新的执行元,而actorSelection则会寻找已经存在的执行元。
我怀疑您的actorSelection不起作用而您的actorFor起作用的原因是因为该actor当前不存在。