【问题标题】:Scala Akka Route Test - ActorRefFactory context must be definedScala Akka 路由测试 - 必须定义 ActorRefFactory 上下文
【发布时间】:2018-02-25 00:41:47
【问题描述】:

Akka Http 版本:“10.0.11”

我有以下测试路线:

private def getAll: Route = pathPrefix("_all") {
  get {
    complete((todoRegistryActor ? GetAllTodos).mapTo[Todos].map(todosToTodoDtos))
  }
}

我有以下测试:

class TodoRouteSpec extends WordSpec with Matchers
  with ScalatestRouteTest with RouteManager with BeforeAndAfterAll with TestKitBase with ImplicitSender {

  override implicit val system: ActorSystem = ActorSystem("TodoRouteSpec")
  override val executionContext: ExecutionContext = system.dispatcher

  private val todoRegistryProbe = TestProbe()
  override implicit val todoRegistryActor: ActorRef = todoRegistryProbe.ref

  override def afterAll {
    TestKit.shutdownActorSystem(system)
  }

  "The service" should {
    "return a list of todos for GET _all request" in {
      Get("/api/todo/_all").~>(todoRoute)(TildeArrow.injectIntoRoute).~>(check {
        //todoRegistryProbe.expectMsg(GetAllTodos)

        responseAs[TodosDto] shouldEqual TodosDto(Seq.empty)
        status should ===(StatusCodes.OK)
      })
    }
  }
}

运行以下测试时,我收到错误: 异常或错误导致运行中止:必须定义 ActorRefFactory 上下文 java.lang.IllegalArgumentException:必须定义 ActorRefFactory 上下文

  1. 我正在寻找引发此错误的原因,但找不到解决方案。 有人知道是什么引发了这个错误吗?
  2. 必须显式传递 TildeArrow.injectIntoRoute 才能使测试运行。在这里找到解决方案:How can I fix the missing implicit value for parameter ta: TildeArrow in a test spec。也许有人知道另一种解决方案?

提前致谢

解决方案

class TodoRouteSpec extends WordSpec with Matchers with ScalatestRouteTest with TodoRoute {

  private lazy val routes = todoRoute
  private val todoRegistryProbe = TestProbe()
  todoRegistryProbe.setAutoPilot((sender: ActorRef, _: Any) => {
    sender ! Todos(Seq.empty)
    TestActor.KeepRunning
  })
  override implicit val todoRegistryActor: ActorRef = todoRegistryProbe.ref

  "TodoRoute" should {
    "return a list of todos for GET /todo/_all request" in {
      Get("/todo/_all").~>(routes)(TildeArrow.injectIntoRoute).~>(check {
        todoRegistryProbe.expectMsg(GetAllTodos)

        status should ===(StatusCodes.OK)
        contentType should ===(ContentTypes.`application/json`)
        entityAs[TodosDto] shouldEqual TodosDto(Seq.empty)
      })
    }
  }
}

【问题讨论】:

    标签: scala akka akka-http


    【解决方案1】:

    你不需要actor系统来做路由测试。

    参见documentation 中的示例。

    class FullTestKitExampleSpec extends WordSpec with Matchers with ScalatestRouteTest {
    
      val smallRoute =
        get {
          path("ping") {
            complete("PONG!")
          }
        }
    
      "The service" should {
    
        "return a 'PONG!' response for GET requests to /ping" in {
          // tests:
          Get("/ping") ~> smallRoute ~> check {
            responseAs[String] shouldEqual "PONG!"
          }
        }
      }
    }
    

    【讨论】:

    • 如果你的服务需要actor系统,你可以使用doc.akka.io/docs/akka/2.5/…中描述的Akka TestKit
    • 感谢您的评论。我确实不需要演员系统。但我想验证是否使用正确的消息调用了演员。因此,您可以使用 TestProbe() 的 setAutoPilot。我将发布我的具体解决方案
    猜你喜欢
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 2020-06-05
    相关资源
    最近更新 更多