弊社ではモックサーバに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