弊社ではモックサーバにWiremockを使用しています。
この記事ではWiremockを知ってもらうきっかけを提供することを目的としています。詳しいことは他の方の記事を参考にした方が良いでしょう。
ゴール
- WiremockのモックサーバでJUnitでテストする
Wiremockのスタンドアロンで起動する機能については、今回は紹介しません。スタンドアロンなら別のいいツールあるかもしれないので。
Wiremockとは
WireMockはHTTPモックサーバー。リクエスト回数やリクエストJSONを確認することもできる。
スタンドアロンとしても立ち上げることができるので、JUnitとの連携だけでなくE2Eテストや検証環境でも使用することができる。
環境
- Java
- 15
- org.springframework.boot
- 2.4.0
- com.github.tomakehurst:wiremock-jre8
- 2.27.2
- ru.lanwen.wiremock:wiremock-junit5
- 1.3.1
単体テストでの使い方
Wiremockが使えるように依存関係に含める
使用できるように依存関係に含めます。デフォルトだとJUnit4の記述しかできないので、JUnit5でも使用できるように関連ライブラリも依存関係に含めます。
Gradleでの記述方法。
testImplementation "com.github.tomakehurst:wiremock-jre8:2.27.2" testImplementation "ru.lanwen.wiremock:wiremock-junit5:1.3.1"
Wiremockをテストクラスで使えるようにする
WiremockResolver.classを読み込みます。
@ExtendWith(WiremockResolver.class)
Wiremockサーバを初期セットアップする
テストクラスのコンストラクタを使用します。
@WiremockResolver.Wiremockをパラメータに付けることで、初期化対象となります。
ランダムポートで生成されるので、テストターゲットに対してパラメータを渡してあげることで並列実行等もできるようになります。
private WireMockServer server; ZipCloudClientImplTests(@WiremockResolver.Wiremock WireMockServer server) { this.server = server; }
@BeforeEach void setup() { ZipCloudClientProperties properties = new ZipCloudClientProperties(); properties.setSchema("http"); properties.setHost("localhost"); properties.setPort(server.port()); properties.setPath("/api/search"); RestOperationFactory restOperationFactory = new RestOperationFactory(restTemplateBuilder, new RestTemplateInterceptor()); RestOperations restOperations = restOperationFactory.createRestOperations(properties); target = new ZipCloudClientImpl(properties, restOperations); }
モックをセットする
あとはWiremockに設定するのみです。
こちらを設定したうえで、テストを実施すると対向システムをモックサーバとした状態でテストできます。
次の記載方法は、特定のURLとクエリパラメータ時に、特定のResponseBodyを返却する書き方となります。
String responseBody =
"""
{
"message":null,
"results": [{
"address1":"神奈川県",
"address2" : "厚木市",
"address3" : "中町",
"kana1" : "カナガワケン",
"kana2" : "アツギシ",
"kana3" : "ナカチョウ",
"prefcode" : "14",
"zipcode" : "2430018"
}],
"status": 200
}""";
server.stubFor(
get("/api/search?zipcode=2430018").willReturn(
aResponse()
.withStatus(200)
.withHeader("Content-Type", "text/plain")
.withBody(responseBody)
)
);
リクエストJSONを比較したい時には、withRequestBodyを使用します。※ソースコードでは比較していません。
String requestBody =
"""
{
"message":null,
"results": [{
"address1":"神奈川県",
"address2" : "厚木市",
"address3" : "中町",
"kana1" : "カナガワケン",
"kana2" : "アツギシ",
"kana3" : "ナカチョウ",
"prefcode" : "14",
"zipcode" : "2430018"
}],
"status": 200
}""";
server.stubFor(
post("/api/search")
.withRequestBody(
equalToJson(requestBody)
)
ソースコード
終わりに
Wiremockが使えると単体テストができるようになるので便利です。
もちろん、できるだけ本番環境でテストできることが最高ですが、相手のサービスのメンテナンス時間が原因でテスト失敗するFlakyなテストになってしまいます。実行するたびに課金されるようなAPIを実行しても厳しいですしね。
知らないだけでもっと便利なJavaのモックサーバはあるかもしれませんが、Spring公式でも紹介されている以上、便利なものでしょう。
JavaとWiremockで調べる人が多いとは思いませんが、一助になればと思います。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考
Wiremock公式サイト wiremock.org
Spring公式のWiremockの使用方法 cloud.spring.io
