mcpField
U
unit-test-wiremock-rest-api

unit-test-wiremock-rest-api

github.com/giuseppe-trisciuoglioテスト・品質3653.8k 回インストール7 週間前に更新
リポジトリ

unit-test-wiremock-rest-api について

外部 REST API 連携をネットワーク依存なしでテストするための WireMock スキルガイドです。レスポンスのスタブ化、リクエスト検証、タイムアウトやエラーのケースを扱います。

主な機能

  1. 01WireMock による HTTP レスポンスのスタブ化
  2. 02URL、ヘッダー、リクエストボディの照合
  3. 03クライアントが送信したリクエストの検証
  4. 04タイムアウトとエラーレスポンスのテスト
  5. 05競合を避ける動的ポートの使用

活用シーン

  1. 01サードパーティ REST API を呼び出すサービスのテスト
  2. 024xx、5xx、タイムアウトの再現
  3. 03リクエストパラメーターやヘッダー、本文の確認
  4. 04ネットワーク非依存テストの並列実行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-wiremock-rest-api

インストール後、Claude Code で/unit-test-wiremock-rest-apiを入力して読み込まれたか確認します。

同梱ファイルreferences/advanced-examples.md

詳細

WireMock を使用した REST API のユニットテスト

概要

WireMock を使用して、外部 REST API との連携をテストするパターンです。レスポンスのスタブ化、リクエストの検証、エラーシナリオのテスト、ネットワークへの依存を排除した高速なテストを扱います。

使用する場面

  • 外部 REST API を呼び出すサービスのテスト
  • 予測可能なテスト動作を実現するための HTTP レスポンスのスタブ化
  • エラーシナリオ(タイムアウト、5xx エラー、不正な形式のレスポンス)のテスト
  • リクエストの詳細(ヘッダー、クエリパラメーター、リクエストボディ)の検証

手順

  1. 依存関係を追加する:テストスコープに WireMock を追加します(Maven/Gradle)
  2. 拡張機能を登録する:dynamicPort() を指定して @RegisterExtension WireMockExtension を登録します
  3. クライアントを設定する:ベース URL として wireMock.getRuntimeInfo().getHttpBaseUrl() を使用します
  4. レスポンスをスタブ化する:リクエストのマッチング(URL、ヘッダー、ボディ)を指定して stubFor() を使用します
  5. 実行してアサートする:サービスメソッドを呼び出し、AssertJ で結果を検証します
  6. リクエストを検証する:正しい API の使用を確認するために verify() を使用します

スタブが一致しない場合:URL エンコーディングとヘッダー名を確認し、クエリパラメーターには urlEqualTo を使用します。

テストがハングする場合:HTTP クライアントで接続タイムアウトを設定し、タイムアウトをシミュレートするには withFixedDelay() を使用します。

ポートが競合する場合:常に wireMockConfig().dynamicPort() を使用します。

使用例

Maven の依存関係
<dependency>
  <groupId>org.wiremock</groupId>
  <artifactId>wiremock</artifactId>
  <version>3.4.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.assertj</groupId>
  <artifactId>assertj-core</artifactId>
  <scope>test</scope>
</dependency>
基本的なスタブ化と検証
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.assertj.core.api.Assertions.assertThat;

class ExternalWeatherServiceTest {

  @RegisterExtension
  static WireMockExtension wireMock = WireMockExtension.newInstance()
    .options(wireMockConfig().dynamicPort())
    .build();

  @Test
  void shouldFetchWeatherDataFromExternalApi() {
    wireMock.stubFor(get(urlEqualTo("/weather?city=London"))
      .withHeader("Accept", containing("application/json"))
      .willReturn(aResponse()
        .withStatus(200)
        .withHeader("Content-Type", "application/json")
        .withBody("{\"city\":\"London\",\"temperature\":15,\"condition\":\"Cloudy\"}")));

    String baseUrl = wireMock.getRuntimeInfo().getHttpBaseUrl();
    WeatherApiClient client = new WeatherApiClient(baseUrl);
    WeatherData weather = client.getWeather("London");

    assertThat(weather.getCity()).isEqualTo("London");
    assertThat(weather.getTemperature()).isEqualTo(15);

    wireMock.verify(getRequestedFor(urlEqualTo("/weather?city=London"))
      .withHeader("Accept", containing("application/json")));
  }
}

エラーシナリオ、ボディの検証、タイムアウトのシミュレーション、状態を保持するテストについては、references/advanced-examples.md を参照してください。

ベストプラクティス

  • 動的ポート:並列テスト実行時の競合を防ぎます
  • リクエストの検証:クライアントが正しく API を使用していることを確認します
  • エラーのテスト:タイムアウト、4xx、5xx のシナリオを網羅します
  • 焦点を絞ったスタブ:テストごとに対象を 1 つにします
  • 自動リセット:@RegisterExtension により、テスト間で WireMock がリセットされます
  • 実際の API を呼び出さない:サードパーティーのエンドポイントは常にスタブ化します

制約と警告

  • 動的ポートが必須:固定ポートは並列実行時に競合を引き起こします
  • HTTPS のテスト:TLS 接続をテストする場合は、WireMock の TLS 設定を行います
  • スタブの優先順位:より具体的なスタブが一般的なスタブより優先されます
  • パフォーマンス:WireMock によってオーバーヘッドが発生します。テストを高速化するには、クライアント層でモックします
  • API の変更:スタブを実際の API コントラクトと同期させます

参考資料

コメント