【Junit】OkHttpClientのテストを実装する in gradle

OkHttpClientを使用したメソッドのテストを実装したい

特に以下の内容を検証したい場合のテスト実装を紹介します

  • リクエストの内容(URL、ヘッダー、ボディ)を正しく送信していることを確認してください
  • 応答の内容を検証し、JSON をオブジェクトに正しく変換しているか確認します

これを達成するために、OkHttpClientの行動をモックし、リクエストが正しく送信されると検証する必要があります!

1. 必要な依存関係を追加

build.gradle次の依存関係を追加して、JUnit5 と Mockito が使えます

dependencies {
    // OkHttpClient
    implementation 'com.squareup.okhttp3:okhttp:4.9.3'
    // Gson for JSON deserialization
    implementation 'com.google.code.gson:gson:2.8.9'

    // JUnit5
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'

    // Mockito
    testImplementation 'org.mockito:mockito-core:3.9.0'
    testImplementation 'org.mockito:mockito-inline:3.9.0'

    // AssertJ for better assertions
    testImplementation 'org.assertj:assertj-core:3.19.0'
}

2. テストしたいメソッド例

OkHttpClientを使用したメソッドを以下の通り実装してみます

また、レスポンスをオブジェクトに変換するために、Gsonを使ってみます
メソッドでレスポンスボディを JSON オブジェクトに変換する処理を追加しました

import okhttp3.*;
import java.io.IOException;
import com.google.gson.Gson;

public class ApiClient {

    private final OkHttpClient client;
    private final String baseUrl;
    private final Gson gson;

    public ApiClient(String baseUrl) {
        this.client = new OkHttpClient();
        this.baseUrl = baseUrl;
        this.gson = new Gson();
    }

    public <T> T sendPostRequest(String endpoint, String jsonBody, String authToken, Class<T> responseType) throws IOException {
        RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));

        Request request = new Request.Builder()
                .url(baseUrl + endpoint)
                .addHeader("Authorization", "Bearer " + authToken)
                .addHeader("Content-Type", "application/json")
                .post(body)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }

            // レスポンスをオブジェクトに変換して返す
            return gson.fromJson(response.body().string(), responseType);
        }
    }
}

3. テストコード(JUnit5 & Mockito)を実装

次に、OkHttpClient をモックして sendPostRequest メソッドの挙動を検証します

import okhttp3.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.*;

import java.io.IOException;

class ApiClientTest {

    private OkHttpClient mockHttpClient;
    private ApiClient apiClient;
    private Call mockCall;
    private Response mockResponse;

    @BeforeEach
    void setUp() {
        mockHttpClient = mock(OkHttpClient.class);
        mockCall = mock(Call.class);
        apiClient = new ApiClient("https://api.example.com");
    }

    @Test
    void testSendPostRequest() throws IOException {
        // モックされたレスポンスの設定
        ResponseBody mockResponseBody = ResponseBody.create("{\"success\": true}", MediaType.get("application/json"));
        mockResponse = new Response.Builder()
                .request(new Request.Builder().url("https://api.example.com/post-endpoint").build())
                .protocol(Protocol.HTTP_1_1)
                .code(200)
                .message("OK")
                .body(mockResponseBody)
                .build();

        // モックが呼び出されたときにレスポンスを返すように設定
        when(mockCall.execute()).thenReturn(mockResponse);
        when(mockHttpClient.newCall(any(Request.class))).thenReturn(mockCall);

        // リクエストの検証用にArgumentCaptorを使う
        ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);

        // 実際のテスト対象メソッドを呼び出し
        TestResponse response = apiClient.sendPostRequest("/post-endpoint", "{\"key\":\"value\"}", "your-token", TestResponse.class);

        // レスポンスが正しくオブジェクトに変換されているかを検証
        assertThat(response.isSuccess()).isTrue();

        // リクエストの内容をキャプチャして検証
        verify(mockHttpClient).newCall(requestCaptor.capture());
        Request capturedRequest = requestCaptor.getValue();

        // リクエスト URL、ヘッダー、ボディの検証
        assertThat(capturedRequest.url().toString()).isEqualTo("https://api.example.com/post-endpoint");
        assertThat(capturedRequest.header("Authorization")).isEqualTo("Bearer your-token");
        assertThat(capturedRequest.header("Content-Type")).isEqualTo("application/json");
        assertThat(capturedRequest.body()).isNotNull();
    }

    // テスト用のレスポンスクラス
    static class TestResponse {
        private boolean success;

        public boolean isSuccess() {
            return success;
        }

        public void setSuccess(boolean success) {
            this.success = success;
        }
    }
}
  1. Mockitoを使ったモック化
    • OkHttpClient と Call のモックを作成し、execute メソッドが呼ばれたときにモックされた Response を返すように設定しています
    • ArgumentCaptor を使ってリクエストの内容(URL、ヘッダー、ボディ)をキャプチャし、後で検証します
  2. レスポンスの検証
    • レスポンスボディの内容({“success”: true})をモックし、メソッドが正しくオブジェクトに変換できることを検証しています
  3. リクエストの内容を検証
    • Request のURL、Authorization ヘッダー、Content-Type ヘッダーが正しいことを確認しています


このテストにより、sendPostRequest メソッドが適切に動作しているかをJunit5とMockitoを使用して効果的に検証できます

これは一例になります

このソースを参考にあなたの実装したメソッドに合ったテストを実装してみてください!

是非フォローしてください

最新の情報をお伝えします