Kotest(Kotlinテストフレームワーク)
概要
実装例
FunSpecを使った実装例。contextを使って階層構造を表現している。
アサーションとして、代表的なとしてshouldBe(イコールみたいなやつ。右辺になるべきとの表現)、shouldThrow(例外になるべき)などがある。
class CalcServiceFunSpecTest : FunSpec() { private val calc = Calc() init { context("CalcServiceTest") { context("正常系") { test("1 + 1 は2になる") { calc.plus(1, 1) shouldBe 2 } } context("異常系") { test("5 ÷ 0 は例外が投げられる") { shouldThrow<ArithmeticException> { calc.divide(5, 0) } } } } } }
MockK(ClassをMock化)
概要
- Kotlin独自の言語仕様をほぼ網羅しているモックライブラリ
Coroutineやobject、private関数などにも対応
参考URL
Wire mock(スタブサーバー構築)
概要
- WireMockを使用して開発環境にスタブサーバーを構築することで、外部サービスとの連携をモックすることができる。
- マイクロサービスのシステムや、外部サービスを利用することが多い場合に有用
実装例
Junit5でWireMockを使用する方法
以下、参考URLから引用させて頂いて、Javaでの記載になっているので注意。
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; class SampleTest { // programmaticモードでの利用は、@RegisterExtensionを付与したWireMockExtensionを定義(複数の設定で定義可) @RegisterExtension static WireMockExtension mock = WireMockExtension.newInstance() // HTTPSでかつポートを3000固定とする設定 .options(WireMockConfiguration.wireMockConfig().httpDisabled(false).port(3000)) .build(); @Test void test() { // Getメソッドで指定URLのときに起動するMockサーバーを定義 mock.stubFor(WireMock.get(WireMock.urlEqualTo("/some/thing?name=Bob")) .withQueryParam("name", WireMock.containing("Bob")) // ヘッダー設定 .withHeader("Content-Type", WireMock.equalTo("application/json")) // スタブを複数定義する場合は、優先度を数値指定。1が最優先で2、3と次に優先される .atPriority(1) // レスポンス設定 .willReturn(WireMock.aResponse() .withHeader("Content-Type", "application/json") .withBody("Hello world!"))); // レスポンスを外部ファイル化する際は、レスポンスボディを定義したファイルのパスを指定する // .withBodyFile("clientTest/get001.json"))); } }
マッピングファイルでスタブを登録する方法
{ // スタブを複数定義する場合は、優先度を数値指定。1が最優先で2、3と次に優先される "priority": 1, "request": { "method": "GET", "url": "/some/thing?name=Bob", "headers" : { "Content-Type": { "equalTo" : "application/json" } }, "queryParameters" : { "name" : { "containing" : "Bob" } } }, "response": { "status": 200, "body": "Hello world!", // レスポンスを外部ファイル化する際は、レスポンスボディを定義したファイルのパスを指定する // "bodyFileName": "clientTest/get001.json", "headers": { "Content-Type": "application/json" } } }
レスポンスを動的に返却する
Response Templatingという機能がある。
二重中括弧({{}})で囲むことで、ifなどの条件式をはじめとする様々なヘルパーを使用可能。
詳しくは以下を参照 Mock API Response Templating | WireMock
- 参考URL
Testcontainers
概要
- Testcontainersはテストコード上でdockerコンテナの起動や停止を制御可能
- 完全にテストコードの中だけで完結し、非常に簡単に導入可能
- Dockerコンテナで実行できるデータベースなどに対して軽量で使い捨て可能なインスタンス提供する
ライブラリ読み込み
TOMLファイルの[libraries]、[plugins]テーブルなどにtestcontainersBomの設定を定義
libs.versions.toml
[versions] javaLanguageVersion = "21" kotlin = "1.9.24" springBoot = "3.3.0" testcontainersBom = "1.20.1" [plugins] kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } spring-boot = { id = "org.springframework.boot", version.ref = "springBoot" } [libraries] testcontainers-bom = { module = "org.testcontainers:testcontainers-bom", version.ref = "testcontainersBom" } org-testcontainers-mysql = { module = "org.testcontainers:mysql" }
利用時の注意点
- docker-compose -dなどで事前にコンテナを立ててしまっていると、テスト実行時に同じportに同じコンテナを起動しようとしてエラーになるので、コンテナ起動済みの場合は停止してからテスト実行する
- Rancher Desktopなどを使っている場合、管理者権限がないとコンテナ作成、停止ができないので、管理者権限でアクセスできるように設定変更しておく。
- 「歯車」アイコン > Application > Administrative Access から、管理者権限をAccept(許可)にします