首页 > 解决方案 > 如何处理在单元测试中返回 Accumultor[ByteString,Result] 的动作

问题描述

我的Action回报Accumulator[ByteString,Result]。我想对Accumulator. 我该如何测试它?我正在尝试使用contentAsJsonwhich 接受类型的变量,Accumulator[ByteString,Result]RightEither 的一侧没有给我内容。以下是测试用例。

  "newQuestion" should {
    "should return error if tag information in the question isn't in correct format" in {
      val testEnv = new QuestionsControllerSpecTestEnv(components=components)
      val body =
        s"""
          |{
          | "practice-question":{
          | "description": "some description",
          | "hints": ["hint1","hint2"],
          | "image": ["image1 data","image2 data"],
          | "success-test": "success test",
          | "fail-test": "fail test",
          | "tags": ["tag1-in-incorrect-format","tag2IsAlsoWrong"],
          | "title":"some title",
          | "answer": "some answer",
          | "references":["ref1","ref2"]
          | }
          |}
        """.stripMargin

      val jsonBody = Json.parse(body)

      val request = new FakeRequest(FakeRequest("POST","ws/questions/new-question")).withAuthenticator(testEnv.testEnv.loginInfo)(testEnv.testEnv.fakeEnv).withBody(AnyContentAsJson(jsonBody))
      val response = testEnv.questionsController.newQuestion(request)
      val responseBody = contentAsJson(response)//(Timeout(Duration(5000,"millis")),testEnv.testEnv.mat)
      println(s"received response body ${responseBody}")
      val result = (responseBody \ "result").get.as[String]
      val additionalInfo = (responseBody \ "additional-info").get.as[String]
      result mustBe "error"
      additionalInfo mustBe components.messagesApi("error.invalidTagStructure")(components.langs.availables(0))
    }
  }

控制器正在接收类型的主体Right(AnyContentAsRaw(RawBuffer(inMemory=0, backedByTemporaryFile=null)))

为什么我在正文中看不到 JSON?

标签: playframework-2.6

解决方案


我需要调用run的方法Accumulator来启动将数据传递给累加器的流。

run方法有 3 个变体。

abstract def run(elem: E)(implicit materializer: Materializer): Future[A]
Run this accumulator by feeding a single element into it.

abstract def run()(implicit materializer: Materializer): Future[A]
Run this accumulator by feeding nothing into it.

abstract def run(source: Source[E, _])(implicit materializer: Materializer): Future[A]
Run this accumulator by feeding in the given source.

E似乎是流的数据类型。就我而言, Accumulator[-E,+A]E等于ByteStream. 所以我将字符串主体转换为 Bytestream 并将其传递给run. run返回Future[Result] which could then be processed usingcontentAsJson method ofHelpers` 类

val body =
        s"""
           |{
           | "practice-question":{
           | "description": "some description",
           | "hints": ["hint1","hint2"],
           | "image": ["image1 data","image2 data","image3 data"],
           | "success-test": "success test",
           | "fail-test": "fail test",
           | "tags": ["${testEnv.tag}","${testEnv.tag}"],
           | "title":"some title",
           | "answer": "some answer",
           | "references":["ref1","ref2"]
           | }
           |}
        """.stripMargin

      val jsonBody = Json.parse(body)

      println("jsBody is "+jsonBody)
...


val request = new FakeRequest(FakeRequest("POST","ws/questions/new-question")).withAuthenticator(testEnv.testEnv.loginInfo)(testEnv.testEnv.fakeEnv).withHeaders(CONTENT_TYPE->"application/json").withBody(AnyContentAsJson(jsonBody))
      val response = testEnv.questionsController.newQuestion(request)
      val accumulatorResult = response.run(ByteString(body)) //use run to start the Accumulator
      val responseBody = contentAsJson(accumulatorResult)//(Timeout(Duration(5000,"millis")),testEnv.testEnv.mat)

..

推荐阅读