Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to respond to an Ask pattern with a failure using Akka TestKit?

I have an Akka Actor which uses the Ask pattern to retrieve a Future from a child actor and acts on both success and failure. I cannot work out how to mock out the child actor and respond with failures.

Here's the code:

import java.util.concurrent.TimeUnit
import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.pattern.ask
import akka.testkit.{ImplicitSender, TestKitBase, TestProbe}
import akka.util.Timeout
import org.specs2.mutable.Specification
import org.specs2.specification.Scope
import scala.util.{Failure, Success}

class Parent(child: ActorRef) extends Actor {
  implicit val timeout = Timeout(5, TimeUnit.SECONDS)
  import context.dispatcher

  override def receive: Receive = {
    case "go" => {
      val senderRef = sender()
      (child ? "question").mapTo[String] onComplete {
        case Success("answer") =>
          senderRef ! "child responded with a successful answer"
        case Failure(throwable) =>
          senderRef ! "child responded with a failure"
      }
    }
  }
}

class SimplifiedProblemSpec extends Specification {

  "The Parent Actor" should {
    "act on success" in new TestScope {
      parent ! "go"
      childProbe.expectMsg("question")
      childProbe.reply("answer")
      expectMsg("child responded with a successful answer")
    }
    "act on failure" in new TestScope {
      parent ! "go"
      childProbe.expectMsg("question")
      // How to reply with failure?
      expectMsg("child responded with a failure")
    }
  }

}

abstract class TestScope extends Scope with TestKitBase with ImplicitSender {
  implicit lazy val system: ActorSystem = ActorSystem()

  val childProbe = TestProbe()
  val parent = system.actorOf(Props(classOf[Parent], childProbe.ref), "Parent")

}

Any help would be much appreciated.

Thank you

like image 573
William Carter Avatar asked Sep 27 '22 17:09

William Carter


1 Answers

You can use Status.Failure case class from akka.actor package. From docs:

This class/message type is preferably used to indicate failure of some operation performed. As an example, it is used to signal failure with AskSupport is used (ask/?).

like image 80
ka4eli Avatar answered Sep 30 '22 07:09

ka4eli