1. 概要

このクイックチュートリアルでは、WireMockを使用してステートフルHTTPベースのAPIをテストする方法を示します。

ライブラリの使用を開始するには、まずWireMockの概要チュートリアルをご覧ください。

2. Mavenの依存関係

WireMockライブラリを利用できるようにするには、POMに次の依存関係を含める必要があります。

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock</artifactId>
    <version>2.21.0</version>
    <scope>test</scope>
</dependency>

3. モックしたいAPIの例

Wiremockのシナリオの概念は、 RESTAPIのさまざまな状態のシミュレーションを支援することです。 これにより、使用しているAPIが状態に応じて異なる動作をするテストを作成できます。

これを説明するために、実際の例を見てみましょう。 / java-tip エンドポイントを要求するたびに、Javaに関する別のヒントを提供する「JavaTip」サービスです。 。

ヒントを求めると、 text /plainに戻ってきます。

"use composition rather than inheritance"

もう一度呼び出すと、別のヒントが得られます。

4. シナリオ状態の作成

“ / java-tip”エンドポイントのスタブを作成するためにWireMockを入手する必要があります。 スタブはそれぞれ、モックAPIの3つの状態の1つに対応する特定のテキストを返します。

public class WireMockScenarioExampleIntegrationTest {
    private static final String THIRD_STATE = "third";
    private static final String SECOND_STATE = "second";
    private static final String TIP_01 = "finally block is not called when System.exit()" 
      + " is called in the try block";
    private static final String TIP_02 = "keep your code clean";
    private static final String TIP_03 = "use composition rather than inheritance";
    private static final String TEXT_PLAIN = "text/plain";
    
    static int port = 9999;
    
    @Rule
    public WireMockRule wireMockRule = new WireMockRule(port);    

    @Test
    public void changeStateOnEachCallTest() throws IOException {
        createWireMockStub(Scenario.STARTED, SECOND_STATE, TIP_01);
        createWireMockStub(SECOND_STATE, THIRD_STATE, TIP_02);
        createWireMockStub(THIRD_STATE, Scenario.STARTED, TIP_03);
        
    }

    private void createWireMockStub(String currentState, String nextState, String responseBody) {
        stubFor(get(urlEqualTo("/java-tip"))
          .inScenario("java tips")
          .whenScenarioStateIs(currentState)
          .willSetStateTo(nextState)
          .willReturn(aResponse()
            .withStatus(200)
            .withHeader("Content-Type", TEXT_PLAIN)
            .withBody(responseBody)));
    }

}

上記のクラスでは、WireMockのJUnitルールクラスWireMockRuleを使用します。 これにより、JUnitテストの実行時にWireMockサーバーがセットアップされます。

次に、WireMockの stubFor メソッドを使用して、後で使用するスタブを作成します。

スタブを作成するときに使用される主な方法は次のとおりです。

  • whenScenarioStateIs :WireMockがこのスタブを使用するためにシナリオがどの状態にある必要があるかを定義します
  • willSetStateTo :このスタブが使用された後にWireMockが状態を設定する値を示します

シナリオの初期状態はScenario.STARTEDです。 したがって、状態が Sceneario.STARTED。の場合に使用されるスタブを作成します。これにより、状態がSECOND_STATEに移動します。

また、スタブを追加して、SECOND_STATEからTHIRD_STATEに移動し、最後にTHIRD_STATEからScenario.STARTEDに戻します。したがって、 / java-tip エンドポイントを呼び出し続けると、状態は次のように変化します。

シナリオ.STARTED->SECOND_STATE->THIRD_STATE->シナリオ.STARTED

5. シナリオの使用

WireMockシナリオを使用するには、 /java-tipエンドポイントを繰り返し呼び出すだけです。 したがって、テストクラスを次のように変更する必要があります。

    @Test
    public void changeStateOnEachCallTest() throws IOException {
        createWireMockStub(Scenario.STARTED, SECOND_STATE, TIP_01);
        createWireMockStub(SECOND_STATE, THIRD_STATE, TIP_02);
        createWireMockStub(THIRD_STATE, Scenario.STARTED, TIP_03);

        assertEquals(TIP_01, nextTip());
        assertEquals(TIP_02, nextTip());
        assertEquals(TIP_03, nextTip());
        assertEquals(TIP_01, nextTip());        
    }

    private String nextTip() throws ClientProtocolException, IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet request = new HttpGet(String.format("http://localhost:%s/java-tip", port));
        HttpResponse httpResponse = httpClient.execute(request);
        return firstLineOfResponse(httpResponse);
    }

    private static String firstLineOfResponse(HttpResponse httpResponse) throws IOException {
        try (BufferedReader reader = new BufferedReader(
          new InputStreamReader(httpResponse.getEntity().getContent()))) {
            return reader.readLine();
        }
    }

nextTip()メソッドは、 / java-tip エンドポイントを呼び出し、応答をStringとして返します。 したがって、各 assertEquals()呼び出しでそれを使用して、呼び出しが実際にシナリオをさまざまな状態で循環させることを確認します。

6. 結論

この記事では、WireMockシナリオを使用して、状態に応じて応答を変更するAPIをモックする方法を説明しました。

いつものように、このチュートリアルで使用されるすべてのコードは、GitHubから入手できます。