WebClientテスト - MockWebServerで外部API呼び出しメソッドをテストする

MockWebServerとは何か、MockWebServerの使い方

概要

最近のほとんどのサービスではREST APIを呼び出すことが想定される。SpringはRESTクライアント構築のためにいくつかの選択肢を提供しており、WebClientを推奨している。

ここでは、WebClientを使ってAPIを呼び出すサービスを単体テストする方法を説明する。

MockWebServerとは?

Squareチームが作成したMockWebServerは、HTTP Requestを受け取りResponseを返す小さくシンプルなWebサーバーである。

WebClientやRestTemplateなどのClientを使ってHTTPを呼び出すメソッドのテストコードを書くとき、このMockWebServerを呼び出すようにすれば簡単にテストコードを書ける。Spring Teamもこの種のテストではMockWebServerの使用を推奨しているという。

簡単なWebClientプロジェクト作成

MockWebServerを使う前に、まずテスト対象となる簡単なWebClientプロジェクトを作成する。サンプルではSpring Initializrを使い、Java 11、Gradle、Spring Boot 2.7.6、webflux依存関係でプロジェクトを生成する。

データを受け取るDTOオブジェクトを作成し、WebClient/users/{id}を呼び出してMono<User>を返すサービスコードを作成する。

MockWebServerの適用

依存関係の追加

MockWebServerを使用するため、テスト依存関係を追加する。

dependencies {
    testImplementation 'com.squareup.okhttp3:mockwebserver'
}

テストコードにMockWebServerを追加

テストコードでは、@BeforeAllMockWebServerオブジェクトを作成して起動し、@AfterAllで終了する。

サービスにWebClientを生成して渡す

MockWebServerのポートを使ったbase URLでWebClientを作成し、サービスへ渡す。

@BeforeEach
void initialize() {
    final String baseUrl = String.format("http://localhost:%s", mockWebServer.getPort());
    final WebClient webClient = WebClient.create(baseUrl);
    userService = new UserService(webClient);
}

このようにすると、テスト実行時に実際の外部URLではなくMockWebServerが呼び出される。

任意のResponseを作成

MockResponseを作成し、bodyとheaderを設定してenqueueに入れる。MockWebServerはenqueueされた順番でレスポンスを返す。

Requestのチェック

レスポンス値だけでなく、takeRequest()を使ってリクエスト内容も確認できる。

final RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertAll(
        () -> assertEquals("GET", recordedRequest.getMethod()),
        () -> assertEquals("/users/3", recordedRequest.getPath())
);

参照


上記のサンプルコードはGitHubで確認できる。