1. 概要

MockitoやEasymockなどの人気のあるモックライブラリは、Javaの継承ベースのクラスモデルを利用してモックアップを生成します。 EasyMockは実行時にインターフェースを実装しますが、Mockitoはターゲットクラスから継承してモックスタブを作成します。

静的メソッドはクラスに関連付けられており、オーバーライドできないため、どちらのアプローチも静的メソッドには適していません。 ただし、JMockitは静的メソッドのモック機能を提供します。

このチュートリアルでは、これらの機能のいくつかについて説明します。

JMockitの概要については、以前の記事をご覧ください。

2. Mavenの依存関係

Mavenの依存関係から始めましょう:

<dependency>
    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.24</version>
    <scope>test</scope>
</dependency>

これらのライブラリの最新バージョンは、 MavenCentralにあります。

3. 非静的メソッドから呼び出された静的メソッド 

まず、静的メソッドに内部的に依存する非静的メソッドを持つクラスがある場合を考えてみましょう。

public class AppManager {

    public boolean managerResponse(String question) {
        return AppManager.isResponsePositive(question);
    }

    public static boolean isResponsePositive(String value) {
        if (value == null) {
            return false;
        }
        int length = value.length();
        int randomNumber = randomNumber();
        return length == randomNumber ? true : false;
    }

    private static int randomNumber() {
        return new Random().nextInt(7);
    }
}

ここで、メソッド managerResponse()。をテストします。その戻り値は別のメソッドに依存するため、 isResponsePositive()メソッドをモックする必要があります。

この静的メソッドを使用してモックすることができます JMockitの匿名クラス mockit.MockUp.MockUp (( ここで、Tはクラス名になります ) と @モック注釈:

@Test
public void givenAppManager_whenStaticMethodCalled_thenValidateExpectedResponse() {
    new MockUp<AppManager>() {
        @Mock
        public boolean isResponsePositive(String value) {
            return false;
        }
    };

    assertFalse(appManager.managerResponse("Some string..."));
}

ここでは、 isResponsePositive()を、テストに使用する戻り値でモックアップしています。 したがって、Junit-5で使用可能なAssertionsユーティリティを使用して期待される結果を検証します。

4. プライベート静的メソッドをテストする

いくつかのケースでは、他のメソッドはクラスのプライベート静的メソッドを使用します。

private static Integer stringToInteger(String num) {
    return Integer.parseInt(num);
}

このようなメソッドをテストするには、プライベート静的メソッドをモックする必要があります。 JMockitが提供するDeencapsulation.invoke()utilityメソッドを使用できます。

@Test
public void givenAppManager_whenPrivateStaticMethod_thenValidateExpectedResponse() {
    int response = Deencapsulation.invoke(AppManager.class, "stringToInteger", "110");
    assertEquals(110, response);
}

名前が示すように、その目的は、オブジェクトの状態をカプセル化解除することです。 このようにして、JMockitは、他の方法ではテストできなかったテスト方法を簡素化します。

5. 結論

この記事では、JMockitを使用して静的メソッドをモックする方法を見てきました。 JMockitの高度な機能の詳細については、JMockitの高度な使用法の記事をご覧ください。

いつものように、このチュートリアルの完全なソースコードは、GitHubからで入手できます。