TestProbe没有收到来自RouteSpec的消息

时间:2018-12-06 15:40:54

标签: scala akka akka-testkit

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

但是,我还没有获得TestProbe来接收一个请求。使用probe.expectMsg(request)时,测试失败,并显示assertion failed: timeout (3 seconds) during expectMsg while waiting for GetCardRequest(12345)。删除expectMsgreply调用仍然会由于Request was rejected块中的check而导致测试失败。我期望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]
            })
        })
    }
}

1 个答案:

答案 0 :(得分: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
  • 我删除了案例类只是为了能够运行它