😸

【JUnit】Mockitoの基本的な使い方

2022/04/12に公開

概要

JUnitでテストをする場合、特定のクラスをモック化してテストを実施する場合がある。
よく使用する内容について使い方を簡単にまとめました。

@Mockと@InjectMocksについて

モック化するクラスは@Mockで設定し、テスト対象のクラスに@InhectMocksを使ってインジェクションする。
※モック化したクラスがテスト対象クラスでインスタンスされてメソッドが呼ばれていた場合、whenなどの設定は無効になるため気を付ける。

@Mock(lenient = true)
private モック化クラス mock;
@InjectMocks
テスト対象クラス testclass;
whenについて

モック化したクラスのメソッドを実行したときの戻り値を設定することができる。
設定方法は2通りある。

1. doReturn(戻り値).when(モックインスタンス).メソッド(引数);
2. when(モックインスタンス.メソッド(引数)).thenReturn(戻り値);
verifyについて

モック化したクラスのメソッド実行回数が想定した回数と一致するかを検証する。

verify(モックインスタンス, times(想定回数)).メソッド(引数);
ArgumentCaptorについて

キャプチャーしたいクラスを設定し、verify実行時の引数として設定することで引数に設定された値をキャプチャーして蓄えることができる。

ArgumentCaptor<キャプチャークラス> captor = ArgumentCaptor.forClass(キャプチャークラス.class);

ソースコード

テストクラス
MockitoSampleTest.java
package com.example.demo;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import com.example.demo.service.MockitoSample;
import com.example.demo.util.Utils;

@ExtendWith(MockitoExtension.class)
public class MockitoSampleTest {
    
    @Mock(lenient = true)
    private Utils utils;
    
    @InjectMocks
    MockitoSample mockitoSample;
    
    /**
     * whenの確認テスト
     */
    @Test
    public void whenTest() {
        // モックインスタンスの戻り値を設定
        doReturn(5).when(utils).checkLenngh("t");
        doReturn(6).when(utils).checkLenngh("te");
        doReturn(7).when(utils).checkLenngh("tes");
        // 以下方法でも設定可能
        when(utils.checkLenngh("test")).thenReturn(8);
        
        // テスト対象メソッド実行
        mockitoSample.testMethod();
        
        // ========コンソール出力内容========
        // 5
        // 6
        // 7
        // 8
    }
    
    /**
     * verifyの確認テスト
     */
    @Test
    public void verifyTest() {
        // テスト対象メソッド実行
        mockitoSample.testMethod();
        
        // モックインスタンスの呼び出し回数を検証
        verify(utils, times(1)).checkLenngh("t");
        verify(utils, times(1)).checkLenngh("te");
        verify(utils, times(1)).checkLenngh("tes");
        verify(utils, times(2)).checkLenngh("test");
        
        // ========JUnitエラー内容========
        // utils.checkLenngh("test");
    }
    
    /**
     * argumentCaptorの確認テスト
     */
    @Test
    public void argumentCaptorTest() {
        // テスト対象メソッド実行
        mockitoSample.testMethod();
        
        // キャプチャー対象の引数を設定
        ArgumentCaptor<String> strCaptor = ArgumentCaptor.forClass(String.class);
        
        // モックインスタンスのメソッドを実行
        verify(utils, times(4)).checkLenngh(strCaptor.capture());
        // キャプチャー内容を出力
        System.out.println(strCaptor.getAllValues());
        
        // ========コンソール出力内容========
        // 0
        // 0
        // 0
        // 0
        // [t, te, tes, test]
    }
}
テスト対象クラス
MockitoSample.java
package com.example.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.util.Utils;

@Service
public class MockitoSample {
    
    @Autowired
    Utils utils;
    
    public void testMethod() {
        // メソッド実行1回目
        System.out.println(utils.checkLenngh("t"));
        
        // メソッド実行2回目
        System.out.println(utils.checkLenngh("te"));
        
        // メソッド実行3回目
        System.out.println(utils.checkLenngh("tes"));
        
        // メソッド実行4回目
        System.out.println(utils.checkLenngh("test"));
    }
}

モック化するクラス
Utils.java
package com.example.demo.util;

import org.springframework.stereotype.Service;

@Service
public class Utils {
    /**
     * テキストの文字数を数える処理
     * @param msg チェック対象文字列
     * @return 文字数
     */
    public int checkLenngh(String msg) {
        return msg.length();
    }
}

git

https://gitlab.com/nk19940709nk/nakaiproject/-/tree/main/ZennProject

Discussion