2017-06-27 44 views
5

Próbuję przetestować metodę kontroler, który próbuje analizować JSON wysłany w zgłoszeniu:Nieprawidłowy Json: Brak treści do map ze względu na końcach wejście przy użyciu analizatora ciała zabaw

def addRoomToProfileForTime = Action.async(parse.json[AddRoomToProfileForTimeRequest]) { request => 
    profileService.addRoomToProfileForTime(request.body.roomId, request.body.profileId, request.body.timeRange).value.map { 
     case Xor.Right(_) => Ok 
     case Xor.Left(err) => BadRequest(Json.toJson(err)) 
    } 
    } 

To jest klasa sprawa, która reprezentuje żądanie:

final case class AddRoomToProfileForTimeRequest(
    roomId: Int, 
    profileId: Int, 
    timeRange: TimeRange 
) 

implicit val addRoomToProfileForTimeRequestFormat:Format[AddRoomToProfileForTimeRequest] = Json.format 

ten kod działa zgodnie z oczekiwaniami robię żądanie tak:

curl -H "Content-Type: application/json" -X POST -d '{"roomId":3,"profileId":1,"timeRange":{"id":1,"fromTime":"2000-01-01T01:01","toTime":"2000-01-01T02:01"}}' http://localhost:9000/api/profiles/addRoomToProfileForTime 

Ale próbuję napisać test dla tej metody (zauważ, że używam macwire do wstrzykiwania zależności, a więc nie można użyć WithApplication:

"add a room to profile for time" in new TestContext { 
    val roomId = 1 
    val profileId = 1 
    val from = "2000-01-01T01:01" 
    val to = "2000-01-01T02:01" 
    val requestJson = Json.obj(
    "roomId" -> roomId, 
    "profileId" -> profileId, 
    "timeRange" -> Json.obj(
     "id"  -> 1, 
     "fromTime" -> from, 
     "toTime" -> to 
    ) 
) 

    implicit val system = ActorSystem() 
    implicit val materializer = ActorMaterializer() 

    val fakeReq = FakeRequest(Helpers.POST, "api/profiles/addRoomToProfileForTime") 
    .withHeaders(CONTENT_TYPE -> "application/json") 
    .withJsonBody(requestJson) 
    val result = profileController.addRoomToProfileForTime()(fakeReq).run 

    val content = contentAsString(result) 
    println(content) 
    status(result) must equalTo(OK) 
} 

Jednak ta próba nie powiedzie się z Bad Request od zaawansowania:

<body>            
    <h1>Bad Request</h1>         

    <p id="detail"> 
     For request 'POST api/profiles/addRoomToProfileForTime' [Invalid Json: No content to map due to end-of-input at [Source: [email protected]; line: 1, column: 0]] 
    </p> 

</body> 

Jeśli przeanalizuję JSON z request.body.asJson, metoda zachowuje się zgodnie z oczekiwaniami. Używam tylko metody parsera powyżej, że dostaję ten błąd.

+0

Mam podobny problem. Niestety, nawet użycie 'request.body.asJson' w kontrolerze nie pomogło w moim przypadku ... – note

+0

Mam inny bardzo podobny projekt z niemal identyczną metodą kontrolera, z wyjątkiem tego, że używam Guice do wstrzykiwania zależności. [Ten przykład] (https://www.playframework.com/documentation/2.5.x/ScalaTestingWithScalaTest#Unit-Testing-EssentialAction) działa dokładnie zgodnie z oczekiwaniami. – felixgb

+1

Poinformowałem o tym problem: https://github.com/playframework/playframework/issues/7877 i utworzono repozytorium testów, aby odtworzyć ten problem: https://github.com/Abrasha/playframework-issue-example –

Odpowiedz

9

Krótka odpowiedź brzmi: na swoim FakeRequest w teście kontrolera używaj metody withBody zamiast withJsonBody.

Miałem również ten problem, a ja zawstydzony spędziłem wiele godzin, aż doszedłem do wniosku. Długa odpowiedź jest taka, że ​​FakeRequest „s withJsonBody zwraca FakeRequest[AnyContentAsJson], a ponieważ kontroler spodziewa się JsValue (nieAnyContentAsJson), podczas rozmowy apply() na działania, które nie pasuje do tej metody stosowania, które jest jednym chcesz :

def apply(request: Request[A]): Future[Result] 

i zamiast hity tego zastosować metodę:

def apply(rh: RequestHeader): Accumulator[ByteString, Result] 

a więc skoro nie jesteś następnie przechodząc żadnych bajtów do a ccumulator, otrzymujesz niespodziewany komunikat o błędzie end-of-input, który otrzymujesz.

+0

Wow Dziękuję bardzo. Też spędziłem wiele godzin na tym. Ten problem wystąpił u mnie podczas aktualizacji z gry 2.5.x do 2.6.x – qwwqwwq