如何使用 Json BodyParser 测试 Play REST API?
How do I test Play REST API with Json BodyParser?
我想为控制器编写一个简单的测试,它接受 json 主体。但是一旦我将 parse.json
BodyParser 添加到 Action 中,我的测试就无法再编译了。
安装程序基本上是普通的 play-scala-seed 项目。
错误:
[error] ... could not find implicit value for parameter mat: akka.stream.Materializer
[error] status(home) mustBe OK
[error] ^
HomeController
:
def index() = Action { implicit request =>
Ok
}
def json() = Action(parse.json) { implicit request =>
Ok
}
HomeControllerSpec
:
class HomeControllerSpec extends PlaySpec with GuiceOneAppPerTest with Injecting {
"HomeController POST" should {
"answer Ok" in {
val controller = new HomeController(stubControllerComponents())
val home = controller.json().apply(FakeRequest(POST, "/"))
status(home) mustBe OK
}
}
看来您需要在您的控制器中注入一个实体化器:
class Controller @Inject() (implicit val mat: Materializer) { ??? }
有关 stubControllerComponents
和 FakeRequest
调用的相关代码似乎存在两个问题。
Helpers.stubControllerComponents
by default constructs ControllerComponents
with NoMaterializer
使用时会抛出异常,因此我们需要提供一个实际的实体化器,如下所示:
implicit val materializer = ActorMaterializer()(ActorSystem())
Helpers.stubControllerComponents(
playBodyParsers = Helpers.stubPlayBodyParsers(materializer)
)
第二个问题是 FakeRequest
,我们需要提供如下正文(否则会出现 4xx
错误):
FakeRequest(POST, "/json").withBody(Json.obj("name" -> "Jon Doe"))
考虑到以上我们可以写出完整的测试如下:
class HomeControllerSpec extends PlaySpec with GuiceOneAppPerTest {
"HomeController POST" should {
"answer Ok" in {
implicit val materializer = ActorMaterializer()(ActorSystem())
val controllerComponents =
Helpers.stubControllerComponents(
playBodyParsers = Helpers.stubPlayBodyParsers(materializer)
)
val controller = new HomeController(controllerComponents)
val fakeRequest =
FakeRequest(POST, "/json").withBody(Json.obj("name" -> "Jon Doe"))
val home = call(controller.json(), fakeRequest)
status(home) mustBe OK
}
}
}
我想为控制器编写一个简单的测试,它接受 json 主体。但是一旦我将 parse.json
BodyParser 添加到 Action 中,我的测试就无法再编译了。
安装程序基本上是普通的 play-scala-seed 项目。
错误:
[error] ... could not find implicit value for parameter mat: akka.stream.Materializer
[error] status(home) mustBe OK
[error] ^
HomeController
:
def index() = Action { implicit request =>
Ok
}
def json() = Action(parse.json) { implicit request =>
Ok
}
HomeControllerSpec
:
class HomeControllerSpec extends PlaySpec with GuiceOneAppPerTest with Injecting {
"HomeController POST" should {
"answer Ok" in {
val controller = new HomeController(stubControllerComponents())
val home = controller.json().apply(FakeRequest(POST, "/"))
status(home) mustBe OK
}
}
看来您需要在您的控制器中注入一个实体化器:
class Controller @Inject() (implicit val mat: Materializer) { ??? }
有关 stubControllerComponents
和 FakeRequest
调用的相关代码似乎存在两个问题。
Helpers.stubControllerComponents
by default constructs ControllerComponents
with NoMaterializer
使用时会抛出异常,因此我们需要提供一个实际的实体化器,如下所示:
implicit val materializer = ActorMaterializer()(ActorSystem())
Helpers.stubControllerComponents(
playBodyParsers = Helpers.stubPlayBodyParsers(materializer)
)
第二个问题是 FakeRequest
,我们需要提供如下正文(否则会出现 4xx
错误):
FakeRequest(POST, "/json").withBody(Json.obj("name" -> "Jon Doe"))
考虑到以上我们可以写出完整的测试如下:
class HomeControllerSpec extends PlaySpec with GuiceOneAppPerTest {
"HomeController POST" should {
"answer Ok" in {
implicit val materializer = ActorMaterializer()(ActorSystem())
val controllerComponents =
Helpers.stubControllerComponents(
playBodyParsers = Helpers.stubPlayBodyParsers(materializer)
)
val controller = new HomeController(controllerComponents)
val fakeRequest =
FakeRequest(POST, "/json").withBody(Json.obj("name" -> "Jon Doe"))
val home = call(controller.json(), fakeRequest)
status(home) mustBe OK
}
}
}