PlayFrameworkでcontrollerのテストどうやるんだろうといろいろ試してみたのでメモ。Play 2.6.3を使っている。
基本的なやり方
play-scala-seed.g8というのに、基本的なControllerとそのテスト方法について書かれているので、それを真似れば良い。
- controller実装: https://github.com/playframework/play-scala-seed.g8/blob/2.6.x/src/main/g8/app/controllers/HomeController.scala
- テスト実装: https://github.com/playframework/play-scala-seed.g8/blob/2.6.x/src/main/g8/test/controllers/HomeControllerSpec.scala
Play 2.6ではControllerは@InjectでControllerComponentsを渡す形式が一般的なので、stubControllerComponents()で得られるテスト用のControllerComponentsを渡せばテストできるっぽい。あとはFakeRequestでテストしたいRequestを作り、いろいろとテストしていくだけ。
自分でControllerのテストの基底クラスを作る
とりあえず真似れば良いのだけど、それだとあまり理解できないので、自分好みのテストのやり方になるようにControllerのテストの基底クラスを作ってみた。PlaySpecの実装を見ながら作った。
test/test/ControllerSpec.scala
package test import org.scalatest.FunSpec import org.scalatestplus.play.guice.GuiceOneAppPerTest abstract class ControllerSpec extends FunSpec with GuiceOneAppPerTest with org.scalatest.Matchers
PlaySpecとの違いは
- 普通にdescribeとかitとかを使ってテストをしたかったので、WordSpecではなくてFunSpecをmixinした
- mustBeじゃなくてshouldBeを使いたかったのでMustMatchersではなくてMatchersをmixinした
- 調べたところmustBeとshouldBeの機能的違いは特に無い http://blog.shibayu36.org/entry/2017/08/30/084816
- あとはアプリケーションを起動できるように(?)、GuiceOneAppPerTestをmixinした
- GuiceOneAppPerTestの役割はまだちゃんと理解は出来ていない
これでこの基底クラスを使って以下のようにテストできる。
test/controllers/HomeControllerSpec.scala
package controllers import play.api.test._ import play.api.test.Helpers._ class HomeControllerSpec extends test.ControllerSpec { describe("HomeController GET") { it("render the index page from a new instance of controller") { val controller = new HomeController(stubControllerComponents()) val home = controller.index().apply(FakeRequest(GET, "/")) status(home) shouldBe OK contentType(home) shouldBe Some("text/html") contentAsString(home) should include ("Welcome to Play") } } }
まとめ
今回はPlay FrameworkでのControllerのテストを試してみた。テストの基底クラスを作ったことで少し理解が深まって良かった。
参考
- https://github.com/playframework/play-scala-seed.g8/blob/2.6.x/src/main/g8/app/controllers/HomeController.scala
- https://github.com/playframework/play-scala-seed.g8/blob/2.6.x/src/main/g8/test/controllers/HomeControllerSpec.scala
- https://github.com/playframework/scalatestplus-play/blob/master/module/src/main/scala/org/scalatestplus/play/PlaySpec.scala
- ScalaTestのshouldBeとmustBeの違いは何か - $shibayu36->blog;