我有一个Akka演员,它使用包含未来的消息。以下是它的简化版本:
case class MyMessage(s: Future[String])
class MyWorker extends Actor {
override def receive: Receive = {
case MyMessage(future) =>
future onComplete {
case Success(s) => sender ! s
case Failure(e) => throw e
}
}
}
我正在使用TestActorRef在specs2中测试它,但是当我编写这样的规范时:
class MyWorkerSpec extends Specification with Mockito {
val worker = TestActorRef(new MyWorker)
"MyMessage" should {
"return the string from a successful result" in {
val message = MyMessage(Future("test"))
val result = worker ? message
result.value.get must_== Success("test")
}
}
}
...然后它以NoSuchElementException: None.get
失败,并且Akka系统抱怨死信。
认为这可能是因为它不等待未来完成,我决定尝试嘲笑未来并抄袭onSuccess
方法。我不知道怎么做,因为func
参数显然是Any
。
class MyWorkerSpec extends Specification with Mockito {
val worker = TestActorRef(new MyWorker)
"MyMessage" should {
"return the string from a successful result" in {
val mockFuture = mock[Future[String]]
mockFuture.onComplete(any[Try[String] => String]) answers {
func => {
func(Success("test"))
}
}
worker ! MyMessage(mockFuture)
}
}
}
如何嘲笑这样的未来?或者有更好的方法吗?
答案 0 :(得分:4)
我认为这里不需要任何嘲弄。
1-如何创建这样的Future
:MyMessage(Future.successful("test"))
,这样就可以在您创建时完成。
2-在value
上致电result
之前,您应该等待您的演员回复:
val result = worker ? message
Await.result(result, duration) must_== Success("test")
请参阅:http://www.scala-lang.org/api/current/index.html#scala.concurrent.Await$
3-向演员发送Future
的实例对我来说听起来很糟糕。