Why does this akka-http route test never succeed?

I have a simple route and some tests that work individually but collectively fail with a 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)
       }
     }
   }
 }

and tests:

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)
}

Edit : Open https://github.com/akka/akka-http/issues/1615

0
source share
2 answers

Working code, thanks to me.

"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")
  }
}

The input TestProbeinside is checkforever, because it creates a dead end; the test expects a callback call, and the callback is not called until the body is completed.

"", , .

0

, TestProbe . TestProbe . , , ; :

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

Source: https://habr.com/ru/post/1650241/


All Articles