【问题标题】:TestProbe not receiving messages from RouteSpecTestProbe 未收到来自 RouteSpec 的消息
【发布时间】:2018-12-06 15:40:53
【问题描述】:

我在尝试“模拟”路线后面的 Actor 时遇到问题。我希望能够在测试时覆盖和模拟功能,我认为 TestProbe 是解决这个问题的正确方法。

但是,我没有得到一个 TestProbe 来接收单个请求。使用probe.expectMsg(request) 时,测试失败并显示assertion failed: timeout (3 seconds) during expectMsg while waiting for GetCardRequest(12345)。删除 expectMsgreply 调用仍将导致测试失败,因为 check 块中的 Request was rejected。我期待 val result = request ~> routes ~> runRoute 能够命中底层的 TestProbe。

我觉得我只是不了解设置的简单内容!提前感谢您的帮助!

class MyRoutesSpec 
  extends WordSpec 
  with Matchers 
  with ScalaFutures 
  with ScalatestRouteTest
  with MyRoutes {
  lazy val routes = MyRoutes

  val probe = new TestProbe(system)
  override val cardLookupActor = probe.ref

  //TODO figure out how to get TestProbe to actually work!!
  "My Routes" should {
    "be able to get a card from a request" in {
      val cardRequest = GetCardRequest("12345")
      val cardRequestEntity = Marshal(cardRequest).to[MessageEntity].futureValue // futureValue is from ScalaFutures
      val request = Post("/getcard").withEntity(cardRequestEntity)
      val cardResponse = ClientCard("Hello", "World")

      val result = request ~> routes ~> runRoute

      probe.expectMsg(cardRequest)
      probe.reply(cardResponse)

      check {
        status should ===(StatusCodes.Created)
        contentType should ===(ContentTypes.`application/json`)
        entityAs[String] should ===("""{"cardName":"Hello", "cardType":"World"}""")
      } (result)
    }
  }
}


trait MyRoutes extends JsonSupport {

  // we leave these abstract, since they will be provided by the App
  implicit def system: ActorSystem

  lazy val log = Logging(system, classOf[MyRoutes])

  // other dependencies that Routes use
  def cardLookupActor: ActorRef

  // Required by the `ask` (?) method below
  implicit lazy val timeout = Timeout(5.seconds) 

  lazy val myRoutes: Route =
    pathPrefix("getcard") {
      concat(
        path(Segment) { id =>
          concat(
            get {
              val cardFuture: Future[ClientCard] =
                (cardLookupActor ? GetCardRequest(id = id)).mapTo[ClientCard]
            })
        })
    }
}

【问题讨论】:

    标签: scala akka akka-testkit


    【解决方案1】:

    您的测试有效,但它只是证明从未调用过测试探针。

    检查这个测试是否通过了

    import akka.Done
    import akka.actor.ActorRef
    import akka.actor.ActorSystem
    import akka.event.Logging
    import akka.http.scaladsl.server._
    import akka.http.scaladsl.server.Directives._
    import akka.http.scaladsl.model.StatusCodes
    import akka.http.scaladsl.testkit.ScalatestRouteTest
    import akka.testkit.TestProbe
    import akka.util.Timeout
    import org.scalatest.Matchers
    import org.scalatest.WordSpec
    import org.scalatest.concurrent.ScalaFutures
    import akka.pattern.ask
    
    import concurrent.duration._
    
    class MyRoutesSpec extends WordSpec with Matchers with ScalaFutures with ScalatestRouteTest with MyRoutes {
    
      val probe = new TestProbe(system)
      override val cardLookupActor = probe.ref
    
      //TODO figure out how to get TestProbe to actually work!!
      "My Routes" should {
        "be able to get a card from a request" in {
          val cardRequest = "12345"
          val request = Get("/getcard/sss").withEntity(cardRequest)
          val cardResponse = "HelloWorld"
    
          val result = request ~> myRoutes ~> runRoute
    
          probe.expectMsg(Done)
          probe.reply(cardResponse)
    
          check {
            status should ===(StatusCodes.OK)
            entityAs[String] should ===("""HelloWorld""")
          }(result)
        }
      }
    }
    
    trait MyRoutes {
    
      // we leave these abstract, since they will be provided by the App
      implicit def system: ActorSystem
    
      lazy val log = Logging(system, classOf[MyRoutes])
    
      // other dependencies that Routes use
      def cardLookupActor: ActorRef
    
      // Required by the `ask` (?) method below
      implicit lazy val timeout = Timeout(5.seconds)
    
      lazy val myRoutes: Route =
        pathPrefix("getcard") {
          path(Segment) { _ =>
            get {
              complete((cardLookupActor ? Done).mapTo[String])
            }
          }
        }
    }
    

    修复了什么

    • lazy val routes = MyRoutes 被移除
    • 您发送Post,但路由需要Get
    • 测试中没有段通过,即/getcard在pathPrefix("getcard") {path(Segment) {id => ???}}中不匹配。
    • 致电request ~> myRoutes ~> runRoute 而不是request ~> routes ~> runRoute
    • 我删除了案例类只是为了能够运行它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-15
      • 2013-09-05
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多