How do I mock a future's onComplete method?
akka, mockito, scala, specs2
Solution
I don't think there is any mocking required here.
1- How about creating your `Future` like this: `MyMessage(Future.successful("test"))`, that way it is completed when you create it.
2- You should wait for your actor to reply before calling `value` on `result`:
val result = worker ? message
Await.result(result, duration) must_== Success("test")
See: http://www.scala-lang.org/api/current/index.html#scala.concurrent.Await$
3- Sending an instance of `Future` to an actor sounds like a terrible idea to me.
Problem
I have an Akka actor that works with a message containing a future. Here is a simplified version of it: ``` 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 } } } ``` I am using TestActorRef to test it in specs2, but when I write a spec like this: ``` 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") } } } ``` ...then it fails with `NoSuchElementException: None.get`, and the Akka system complains about dead letters. Figuring that this is probably because it isn't waiting for the future to complete, I decided to try mocking the future and stubbing the `onSuccess` method. I'm not sure how to do this, though, because the `func` argument is evidently an `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) } } } ``` How does one mock a future like this? Or is there a better way to do it?