Akka-Http:如何TestProbe请求

时间:2016-06-12 19:39:56

标签: scala unit-testing akka akka-http

我有一个请求,其响应取决于演员回复。我试图以这种方式测试它:

val myActor:TestProbe = TestProbe()

val route = new MyRoute() {
    override def myServiceActor:ActorRef = {
        myActor.ref
    }
}.route

"return a query result for GET" in {
    Get("/foo") ~> route ~> check {
        myActor.expectMsg(ExecuteFoo())
        myActor.reply(FOO)
        responseEntity shouldEqual toJsonEntity(RequestResult(FOO))
    }
}

我认为expectMsg已经过验证,但replyresponseEntity检查异步相关。在这种情况下,测试失败。

有没有办法等待回复?

2 个答案:

答案 0 :(得分:6)

您使用TestProbe进入了正确的轨道。关键是将运行请求的组合分开,然后将其检查(通过check将其作为一步执行)分为两个明确的步骤。首先运行它,然后对TestProbe进行任何存根,最后进行检查。您的示例的更新代码如下所示:

  val result = Get("/foo") ~> route ~> runRoute
  myActor.expectMsg(ExecuteFoo())
  myActor.reply(FOO)

  check {
      responseEntity shouldEqual toJsonEntity(RequestResult(FOO))
  }(result)

你可以看到我首先使用runRoute来简单地运行路线而不进行任何检查。我将此值分配给result,因为稍后我将需要它来执行任何检查。然后,您可以安全地对TestProbe进行存根。此时,它已收到该消息,正在等待您的呼叫,以验证它获得了什么消息以及如何响应。然后,完成后,我们可以调用check,将显式结果(来自runRoute的结果)传递给该调用,而不是依赖于隐式。

如果您遵循这种方法,您应该能够使用TestProbe正确测试调用演员的路线。

答案 1 :(得分:0)

执行此操作的一种方法(可能不是正确的或唯一的方法)是使用AutoPilot。这是一个例子:

val myProbe = TestProbe()
myProbe.setAutoPilot(new TestActor.AutoPilot {
  def run(sender: ActorRef, msg: Any) = msg match {
    case ExecuteFoo(_) =>
      //do something else if needed
      sender ! FOO
      TestActor.NoAutoPilot
  }
})