今回はZIOの単体テストを見ていきます。
バックエンド編のzio-httpで作成したApplicationService.postTestが正しい値を返すことを確認するテストを行いたいと思います。
セットアップ
ZIOによる単体テストを行うために以下をbuild.sbtへ追加します。
lazy val root = (project in file("."))
(中略)
libraryDependencies += "dev.zio" %% "zio-http" % "3.0.0-RC2",
libraryDependencies ++= Seq(
"dev.zio" %% "zio-test" % "2.0.17" % Test,
"dev.zio" %% "zio-test-sbt" % "2.0.17" % Test,
"dev.zio" %% "zio-test-magnolia" % "2.0.17" % Test
),
testFrameworks +=
new TestFramework("zio.test.sbt.ZTestFramework")
)
テストコード
テストコードについてはプロジェクトルートからsrc/test/scala配下に配置します。
今回以下のファイル名と内容で配置します。
object TrainingSpec extends ZIOSpecDefault {
def spec: Spec[Any, Throwable] = suite("単体テストトレーニング")(
test("「postTest」が正しい値を返す") {
for {
test <- ZIO.succeed("test")
uri <- ZIO.fromEither(URL.decode("http://localhost:8080/postTest"))
req <- ZIO.attempt(
Request
.default(
Method.POST,
uri,
Body.fromString(
s"userName=$test"
)
)
)
res <- ApplicationService.postTest(req)
bodyString <- res.body.asString
} yield assertTrue(bodyString == s"あなたの名前は${test}です。")
}.provide(ApplicationServiceImpl.layer, Client.default)
)
}
これをsbt testで実行するとテストが成功することが確かめられると思います。
また、IntelliJにZIOプラグインを導入されている方は以下の画像の赤枠のボタンからも実行でき、確認できるかと思います。

詳細部分について見ていきます。
ZIOSpecDefaultの継承
これまでのZIOプログラムの実行の際にはZIOAppDefaultを継承して実行してきましたが、単体テストの場合にはZIOSpecDefault を継承します。
テスト項目設定
テスト項目の設定についてはsuite関数、test関数で行います。
suite関数がテスト項目のグルーピングを担い、test関数が個々のテストを表しています。
test関数内にテストコードを書きます。
実処理部分
実処理部分についてはTestControllerからApplicationService.postTest関数が呼び出される場合自動的にRequestが作成され、引数として渡されますが、今回の場合は自動的には渡されないため、実際のRequestインタスタンスを模したものを作成し、代わりに渡しています。
アサーション
最終的なレスポンスボディの値が正しいものであるかの判定をassertTrue関数で行っています。
DI
また、依存するオブジェクトについてDIを行う必要があるため、こちらについても通常の場合と同様にprovide関数によりDIを行っています。
終わりに
今回はZIOの単体テストについて見てきました。
今回の記事で終わりです。
ご意見、ご感想、誤っているところなどありましたらお気軽にご連絡頂ければ幸いです。
それでは失礼します。
演習
- 今回の単体テストの例について実際に動かし、挙動を確かめてください。
- 解答例は以下になります。
https://github.com/hatuda/zio-practice/tree/CHAPTER9
- 解答例は以下になります。