【Junit】staticメソッドをMockする

目次

はじめに

お世話にになります、hosochinです
さて、今回は
「staticメソッドをMockする」
です

サンプル

テスト対象のソース

  • テスト対象のクラス
import org.springframework.stereotype.Service;

@Service
public class SampleService {
    public String sampleMethod() {
        // staticメソッドを呼ぶ
        return SampleStatic.staticMethod();
    }
}
  • staticメソッドを持つクラス
public class SampleStatic {
    public static String staticMethod() {
        return "real method";
    }
}

テストソース

  • build.gradleに以下を追加します
  • バージョンは適宜いい感じに指定してください
dependencies {
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.junit.jupiter:junit-jupiter:5.7.0'
	testImplementation 'org.mockito:mockito-core:3.6.0'
	testImplementation 'org.mockito:mockito-junit-jupiter:3.6.0'

	testImplementation 'org.mockito:mockito-inline:3.6.0'
}
  • テストクラス
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

import static org.mockito.Mockito.mockStatic;

class SampleServiceTest {

    // テスト対象のクラス
    private final SampleService target = new SampleService();

    @Test
    void test1() {
        // 何もせず実行
        System.out.println(target.sampleMethod()); // real methodと出力される

        // staticなメソッドをMockする
        MockedStatic<SampleStatic> mockedStatic = mockStatic(SampleStatic.class);
        mockedStatic.when(SampleStatic::staticMethod).thenReturn("mocked method");

        // Mockしてから実行
        System.out.println(target.sampleMethod()); // mocked methodと出力される

        // closeしとかないと以降のテストで失敗する
        mockedStatic.close();
    }

    /**
     * test1をtry-with-resources使って書いてみる
     */
    @Test
    void test2() {
        System.out.println(target.sampleMethod()); // real methodと出力される

        try (MockedStatic<SampleStatic> mockedStatic = mockStatic(SampleStatic.class)) {
            mockedStatic.when(SampleStatic::staticMethod).thenReturn("mocked method");

            // Mockしてから実行
            System.out.println(target.sampleMethod()); // mocked methodと出力される
        }
    }
}

まとめ

はい、staticなメソッドをMockできたかと思います👍
ポイントはちゃんとclose()呼ぶことです
try-with-resources使えば勝手に呼ばれますが、test1の書き方でclose()を書かない場合、クラス単位でテスト実行すると以下のエラーが出るので要注意です

To create a new mock, the existing static mock registration must be deregistered

try-with-resources使って書く方が良さそうっすね😎

技術Java,junit,SpringBoot

Posted by hosochin