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

chy5wohz  于 2023-08-05  发布在  Scala
关注(0)|答案(2)|浏览(115)

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

cgvd09ve

cgvd09ve1#

关于stubControllerComponentsFakeRequest调用的代码似乎有两个问题。
默认情况下,Helpers.stubControllerComponents使用NoMaterializer构造ControllerComponents,在使用时只会抛出一个异常,因此我们需要提供一个实际的物化器,如下所示:

implicit val materializer = ActorMaterializer()(ActorSystem())

       Helpers.stubControllerComponents(
         playBodyParsers = Helpers.stubPlayBodyParsers(materializer)
       )

字符串
第二个问题是FakeRequest,我们需要提供一个body,如下所示(否则我们会得到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
    }
  }
}

更新2023年

apply方法ActorMaterializer()已被弃用,目前推荐的构建物化器示例的方法如下。

implicit val materialzer = SystemMaterializer(ActorSystem()).materializer

oknrviil

oknrviil2#

看起来你需要在你的控制器中注入一个物化器:
第一个月

相关问题