2012-10-29 3 views
6

Ich habe die folgende AktionSpiel Rahmen 2: testen Sie eine Anforderung mit einem JSON-String als Körper

def save() = Action(parse.json) { implicit request => 
    request.body.asOpt[IdeaType].map { ideatype => 
    ideatype.save.fold(
     errors => JsonBadRequest(errors), 
     ideatype => Ok(toJson(ideatype)) 
    ) 
    }.getOrElse  (JsonBadRequest("Invalid type of idea entity")) 
} 

Und ich mag es testen

Der Web-Dienst arbeitet mit curl wie dies ok:

curl -X post "http://localhost:9000/api/types" 
--data "{\"name\": \"new name\", \"description\": \"new description\"}" 
--header "Content-type: application/json" 

, die korrekt die neue Ressource zurückgibt

{"url":"/api/types/9","id":9,"name":"new name","description":"new description"} 

Ich versuche, es zu testen mit

"add a new ideaType, using route POST /api/types" in { 
    running(FakeApplication(additionalConfiguration = inMemoryDatabase())) { 

    val json = """{"name": "new name", "description": "new description"}""" 

    val Some(result) = routeAndCall(
     FakeRequest(
     POST, 
     "/api/types", 
     FakeHeaders(Map("Content-Type" -> Seq("application/json"))), 
     json 
    ) 
    ) 

    status(result) must equalTo(OK) 
    contentType(result) must beSome("application/json") 
    val Some(ideaType) = parse(contentAsString(result)).asOpt[IdeaType] 

    ideaType.name mustEqual "new name" 

    } 
} 

Aber ich die folgende Fehlermeldung erhalten:

[error] ! add a new ideaType, using route POST /api/types 
[error]  ClassCastException: java.lang.String cannot be cast to play.api.libs.json.JsValue (IdeaTypes.bak.scala:35) 
[error] controllers.IdeaTypes$$anonfun$save$1.apply(IdeaTypes.bak.scala:36) 
[error] controllers.IdeaTypes$$anonfun$save$1.apply(IdeaTypes.bak.scala:35) 
[error] play.api.mvc.Action$$anon$1.apply(Action.scala:170) 

ich die Hinweise zu dieser Frage gefolgt: Play 2 - Scala FakeRequest withJsonBody

bin ich etwas fehlt ?

-

Kim Stebel Lösung funktionierte gut, aber dann habe ich versucht, mit withJsonBody, wie folgt aus:

val jsonString = """{"name": "new name", "description": "new description"}""" 
    val json: JsValue = parse(jsonString) 

    val Some(result) = routeAndCall(
     FakeRequest(POST, "/api/types"). 
     withJsonBody(json) 
    ) 

und ich erhalte den folgenden Fehler:

[error] ! add a new ideaType, using route POST /api/types 
[error]  ClassCastException: play.api.mvc.AnyContentAsJson cannot be cast to play.api.libs.json.JsValue (IdeaTypes.bak.scala:35) 
[error] controllers.IdeaTypes$$anonfun$save$1.apply(IdeaTypes.bak.scala:36) 
[error] controllers.IdeaTypes$$anonfun$save$1.apply(IdeaTypes.bak.scala:35) 

eine Idee?

+0

, auf der Linie wird der excepton auftreten? –

+0

Die Ausnahme tritt in der Zeile "def save() = Aktion ..." auf ... – opensas

+0

Fügen Sie Ihren routeAndCall kann helfen. – wliao

Antwort

9

Sie müssen wahrscheinlich eine JsValue als den Körper der Anfrage übergeben. Ändern Sie die Zeile

val json = """{"name": "new name", "description": "new description"}""" 

zu

val jsonString = """{"name": "new name", "description": "new description"}""" 
val json = Json.parse(jsonString) 
+0

Sie haben Recht, Kim. Aber ich dachte, dass der FakeRequest es analysieren sollte. Wenn ich es aus curl verwende, sende ich nur eine Zeichenfolge ... – opensas

+1

Aber in diesem Fall wird es vom Framework geparst, bevor das Anfrageobjekt erstellt wird. –

+0

klingt ziemlich logisch. Jetzt versuche ich mit jsonBody, einen weniger ausführlichen Code zu haben, aber es funktioniert nicht ... (Ich habe die Frage bearbeitet ...) – opensas

Verwandte Themen