我有在测试中重写actorOf的特性:
trait ActorRefFactory {
this: Actor =>
def actorOf(props: Props) = context.actorOf(props)
}我有一位演员,当我收到任何信息时,他们会停止自我:
class WorkerActor extends Actor {
override def receive: Actor.Receive = {
case _ => { context.stop(self) }
}
}此外,我还有一位演员大师,他创造演员,并将他们放在队列中:
class MasterActor extends Actor with ActorRefFactory {
var workers = Set.empty[ActorRef]
override val supervisorStrategy = SupervisorStrategy.stoppingStrategy
def createWorker() = {
val worker = context watch actorOf(Props(classOf[WorkerActor]))
workers += worker
worker
}
override def receive: Receive = {
case m: String =>
createWorker()
case Terminated(ref) =>
workers -= ref
createWorker()
}
}这个测试失败了:
class ActorTest(val _system: ActorSystem) extends akka.testkit.TestKit(_system)
with ImplicitSender
with Matchers
with FlatSpecLike {
def this() = this(ActorSystem("test"))
def fixture = new {
val master = TestActorRef(new MasterActor() {
override def actorOf(props: Props) = TestProbe().ref
})
}
it should "NOT FAILED" in {
val f = fixture
f.master ! "create"
f.master ! "create"
f.master.underlyingActor.workers.size shouldBe 2
val worker = f.master.underlyingActor.workers.head
system.stop(worker)
Thread.sleep(100)
f.master.underlyingActor.workers.size shouldBe 2
}
}在测试Thread.sleep之后,我给出了"1不等于2“的错误。我不知道发生了什么。但是,如果猜测我可以假设TestProbe()不能在时间内创建。我能做什么?
发布于 2014-10-22 19:46:02
这基本上归结为一个异步问题,您希望在Akka的单元测试中尽量避免这个问题。您正确地使用了TestActorRef来连接到master参与者的CallingThreadDispatcher中。但是,当您调用system.stop(worker)时,system仍然使用默认的异步调度程序,它将在停止时引入此争用条件,然后重新创建一个工作人员。要想始终如一地解决这个问题,我能看到的最简单的方法是像这样阻止工人:
master.underlyingActor.context.stop(worker)因为您使用的是context of master,而该参与者正在使用CallingThreadDispatcher,所以我相信这将消除您正在看到的asnyc问题。当我试着的时候它对我有用。
https://stackoverflow.com/questions/26508226
复制相似问题