如何使用Json BodyParser测试Play REST API?

时间:2018-03-21 15:15:41

标签: scala playframework scalatest playframework-2.6

我想为控制器编写一个简单的测试,它接受一个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
    }
  }

2 个答案:

答案 0 :(得分:3)

您似乎需要在控制器中注入一个物料化工具:

class Controller @Inject() (implicit val mat: Materializer) { ??? }

答案 1 :(得分:1)

有关stubControllerComponentsFakeRequest来电的相关代码似乎存在两个问题。

Helpers.stubControllerComponents默认使用NoMaterializer构造ControllerComponents,它在使用时会抛出异常,因此我们需要提供一个实际的材质化工具,如下所示:

       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
    }
  }
}