Scala play framework 2:使用json字符串作为主体测试请求
我有以下行动Scala play framework 2:使用json字符串作为主体测试请求,scala,testing,playframework-2.0,specs2,Scala,Testing,Playframework 2.0,Specs2,我有以下行动 def save() = Action(parse.json) { implicit request => request.body.asOpt[IdeaType].map { ideatype => ideatype.save.fold( errors => JsonBadRequest(errors), ideatype => Ok(toJson(ideatype)) ) }.getOrElse (
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"))
}
我想测试一下
web服务可以与curl一起正常工作,如下所示:
curl -X post "http://localhost:9000/api/types"
--data "{\"name\": \"new name\", \"description\": \"new description\"}"
--header "Content-type: application/json"
val jsonString = """{"name": "new name", "description": "new description"}"""
val json: JsValue = parse(jsonString)
val Some(result) = routeAndCall(
FakeRequest(POST, "/api/types").
withJsonBody(json)
)
正确返回新资源的
{"url":"/api/types/9","id":9,"name":"new name","description":"new description"}
我正试着用这个来测试它
"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"
}
}
但我得到了以下错误:
[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)
[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)
我遵循了关于这个问题的建议:
我错过什么了吗
--
Kim Stebel解决方案效果很好,但后来我尝试使用JsonBody,如下所示:
curl -X post "http://localhost:9000/api/types"
--data "{\"name\": \"new name\", \"description\": \"new description\"}"
--header "Content-type: application/json"
val jsonString = """{"name": "new name", "description": "new description"}"""
val json: JsValue = parse(jsonString)
val Some(result) = routeAndCall(
FakeRequest(POST, "/api/types").
withJsonBody(json)
)
我得到以下错误:
[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)
[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)
有什么想法吗?您可能需要传入一个
JsValue
作为请求的主体。换线
val json = """{"name": "new name", "description": "new description"}"""
到
异常发生在哪一行?异常发生在“def save()=Action…”行…粘贴您的路由调用可能会有帮助。我的路由调用在那里…您说得对,kim。但我认为伪造者应该解析它。当我从curl中使用它时,我只是发送一个字符串……但是在这种情况下,在创建请求对象之前,它会被框架解析。听起来很合乎逻辑。现在我正在尝试使用withJsonBody,以获得一个不那么冗长的代码,但它不起作用。。。(我编辑了问题…)James Roper描述了这一点,他说使用
parse.json
的控制器将要求您发送请求[JsValue]
。然而,直到我使用FakeRequest(POST,“/mypath”).withHeaders(“Content type”->“application/json”).withBody[JsValue](json)
,其中json是一个JsObject
,创建了一个请求之后,我才能让它工作。