为什么此akka-http路由测试无法成功完成? [英] Why does this akka-http route test never complete successfully?

查看:124
本文介绍了为什么此akka-http路由测试无法成功完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一条简单的路线,并且有一些测试可以单独成功,但随着超时而集体失败。知道为什么吗?

I've a simple route and some tests that success individually, but collectively fail with timeout. Any idea why?

val route = (requestHandler: ActorRef @@ Web) => {
   get {
     pathPrefix("apps") {
       pathEndOrSingleSlash {
         completeWith(implicitly[ToEntityMarshaller[List[String]]]) { callback =>
           requestHandler ! GetAppsRequest(callback)
         }
       } ~ path("stats") {
         completeWith(implicitly[ToEntityMarshaller[List[Stats]]]) { callback =>
           requestHandler ! GetStatsRequest(callback)
         }
       }
     } ~ path("apps" / Segment / "stats") { app =>
       completeWith(implicitly[ToEntityMarshaller[Stats]]) { callback =>
         requestHandler ! GetStatsForOneRequest(app, callback)
       }
     }
   }
 }

和测试:

val testProbe = TestProbe()
val testProbeActor = testProbe.ref
  .taggedWith[Web]

val timeout = 1.minute

"Route" should "respond to get apps request" in {
  implicit val routeTestTimout = RouteTestTimeout(timeout.dilated)
  Get("/apps") ~> route(testProbeActor) ~> check {

    testProbe.receiveOne(timeout) match {
      case GetAppsRequest(callback) => {
        callback(k8SProperties.apps)
      }
    }
    entityAs[List[String]] should contain("test")
  }
  testProbe.expectNoMessage(timeout)
}

it should "respond to get stats request for all apps" in {
  implicit val routeTestTimout = RouteTestTimeout(timeout.dilated)
  val app = "test"
  Get("/apps/stats") ~> route(testProbeActor) ~> check {

    testProbe.receiveOne(timeout) match {
      case GetStatsRequest(callback) => {
        callback(List(Stats(app, ChronoUnit.SECONDS, Nil)))
      }
      case other => fail(s"Unexpected message $other.")
    }
    entityAs[List[Stats]].size shouldBe (1)
    entityAs[List[Stats]].head.app shouldBe (app)
  }
  testProbe.expectNoMessage(timeout)
}

it should "respond to get stats request for one app" in {
  implicit val routeTestTimout = RouteTestTimeout(timeout.dilated)
  val app = "test"
  Get(s"/apps/$app/stats") ~> route(testProbeActor) ~> check {

    testProbe.receiveOne(timeout) match {
      case GetStatsForOneRequest(app, callback) => {
        callback(Stats(app, ChronoUnit.SECONDS, Nil))
      }
      case other => fail(s"Unexpected message $other.")
    }
    entityAs[Stats].app shouldBe (app)
  }
  testProbe.expectNoMessage(timeout)
}

编辑
已打开> https://github.com/akka/akka-http/issues/1615

推荐答案

工作代码,谢谢我。

"Routes" should "respond to get apps request" in {
  testProbe.setAutoPilot((_: ActorRef, msg: Any) => {
    msg match {
      case GetAppsRequest(callback) => callback(List("test")); TestActor.KeepRunning
      case _ => TestActor.NoAutoPilot
    }
  })

  Get("/apps") ~> handler ~> check {
    entityAs[List[String]] should contain("test")
  }
}

check 内放入 TestProbe 可能永远挂起,可能是因为它产生了死锁;测试等待回调被调用,并且回调直到主体执行后才被调用。

Putting TestProbe inside check hangs forever probably because it creates a deadlock; test waits for callback to be called, and callback isn't called until the body is executed.

使用自动驾驶仪可以设置期望值,稍后可以实现,从而避免了僵局。

Using autopilot sets up an "expectation" that can be fulfilled later thus avoiding the deadlock.

这篇关于为什么此akka-http路由测试无法成功完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆