я работаю над плей-2,4 проекта, и написал контроллер, как:play2:. FakeRequest() withBody (корпус) автоматически преобразуется в запрос [AnyContentAsEmpty] в контроллере
package controllers
import play.api._
import play.api.mvc._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
class Application extends Controller {
def index = Action.async { implicit request =>
Future { Ok(request.body.asJson.get) }
}
}
с POST/controllers.Application.index
в conf/routes
.
Я проверил, что это сработало, выполнив curl --request POST --header "Content-type: application/json" --data '{"foo":"bar"}' http://localhost:9000/
.
Теперь я написал спецификации для этого контроллера:
package controllers
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import play.api.test._
import play.api.test.Helpers._
@RunWith(classOf[JUnitRunner])
class ApplicationSpec extends Specification {
"Application" should {
val controller = new Application
val fakeJson = """{ "foo":"bar" }"""
val fakeRequest = FakeRequest()
.withHeaders("Content-type" -> "application/json")
.withBody(fakeJson)
val index = controller.index()(fakeRequest).run
status(index) must equalTo(OK)
}
}
, но это привело к ошибке во время выполнения:
[error] None.get (Application.scala:11)
[error] controllers.Application$$anonfun$index$1$$anonfun$apply$1.apply(Application.scala:11)
[error] controllers.Application$$anonfun$index$1$$anonfun$apply$1.apply(Application.scala:11)
Я вставленной println(request.body)
в контроллере и нашли тело запроса было AnyContentAsEmpty
, т.е. fakeJson
был удален из fakeRequest
.
Как правильно подключить JSON к FakeRequest?
* примечание: хотя я могу написать как FakeRequest(POST, '/', FakeHeaders(), fakeJson)
, но я думаю, что это не хорошо, потому что спецификация контроллера не должна обрабатывать HTTP-методы или маршруты.
Буду признателен за любую помощь.
Благодарим за подробный ответ. Я хотел бы задать еще одну вещь: почему контроллер с 'parse.json' НЕ анализирует тело' fakeRequest' (это строка), в то время как он автоматически анализирует тело запроса «POST» от клиента (что-то вроде «завитки»)? В чем разница? – iTakeshi
UPDATE: изменено как ваше предложение, но тест не компилируется, говоря, что 'index' является экземпляром' play.api.libs.iteratee.Iteratee [Array [Byte], play.api.mvc.Result] ', но компилятор требует, чтобы он был «scala.concurrent.Future [play.api.mvc.Result]», как ожидает Action.async. Я попытался изменить тестовый код на 'status (index.run)' и скомпилирован, но пришел с ошибкой времени выполнения (ответ HTML сказал '[Ожидание текста/json или application/json body]' со статусом 415). Как я могу решить эту ситуацию? – iTakeshi
'val index = new Application(). Index() (FakeRequest(). WithBody (Joo.obj (" foo "->" bar ")))', за которым следует 'status (index), должен равныйTo (OK)' работает для меня (тест компилируется и проходит). – danielnixon