【8/27まで】Udemyの人気コースが今なら1,200円から!!

【Mockito入門】JavaのユニットテストライブラリMockitoの使い方

【Mockito入門】JavaのユニットテストライブラリMockitoの使い方

導入方法

Mavenを使用している場合、pom.xmlに以下を追記すればOKです。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>1.10.19</version>
</dependency>

Mock(モック)とは

モックとは、要するにハリボテという意味です。
テスト対象のクラスが「まだ実装が完了していないクラス」を呼び出したときに、モックを使えば仮の値を返却させることができるようになります。

どんなときにMockitoを使うのか

例えば、以下のようなCalc.javaを作りました!これのテストコードを書きたいです!
でも、Calc.javaの中で呼んでるSubCalc.javaの実装はまだ終わっていません(泣)というときに使います。
Mockitoを使えば、SubCalc.javaの実装がまだ終わっていなくてもCalc.javaのテストコードを書くことが可能です。


Calc.java

package products;

public class Calc {
	private SubCalc subCalc;

	public Calc(){
		this.subCalc = new SubCalc();
	}

	public int add(){

        int x = this.subCalc.getValA();
        int y = this.subCalc.getValB();
        int z = this.subCalc.getValC(x, y);

        return x + y + z;
	}
}

SubCalc.java

package products;

public class SubCalc {
    public int getValA(){
    	// まだ開発途中
        return 1;
    }
    public int getValB(){
    	// まだ開発途中
    	return 1;
    }
    public int getValC(int x, int y){
    	// まだ開発途中
    	return 1;
    }
}

テストコード

CalcTest.java

package products;

import static org.junit.Assert.*;
import static org.mockito.Matchers.*;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

public class CalcTest {

	@InjectMocks
	private Calc calc;

	@Mock
	private SubCalc subCalc;

    @Before
    public void initMocks() {
        MockitoAnnotations.initMocks(this);
        System.out.println("initMocksが呼ばれました。");
    }

	@Test
	public void test01(){

		// SubCalcクラスの「getValA」メソッドをモックし、実行された場合は3を返す。
        Mockito.doReturn(3).when(subCalc).getValA();

        // SubCalcクラスの「getValB」メソッドをモックし、実行された場合は4を返す。
        Mockito.doReturn(4).when(subCalc).getValB();

        // SubCalcクラスの「getValC」メソッドをモックし、実行された場合は5を返す。
        Mockito.doReturn(5).when(subCalc).getValC(anyInt(), anyInt());

        // 実行して結果を受け取る
		int actual = calc.add();

		// 期待値の設定
		int expected = 12;

		// 検証
		assertEquals(expected,actual);
	}

	@Test
	public void test02(){
		// ここは空振りするけど、initMocksは実行される。
	}
}

解説

@InjectMocksアノテーション

テスト対象のクラスに対して、このアノテーションを付与します。
今回テストしたいクラスはCalc.javaなので、このクラスに付けています。
そうすることで@Mockアノテーションを付けたクラスのインスタンスを自身に注入することができます。

@Mockアノテーション

「まだ実装が完了していないクラス」に対して、このアノテーションを付与します。
そうすることで、実装中の未完成のメソッドを呼び出しても仮の値を返却させるように処理を記述することができるようになります。それをモック化といいます。

@BeforeアノテーションとMockitoAnnotations.initMocks(this)

今回、initMocks()@Beforeを付けています。
@Beforeを付けたinitMocks()は、テストメソッドが実行される前に必ず処理が実行されるようになります。
つまり、各テストメソッドの実行前にMockitoAnnotations.initMocks(this)を実行しているということになります。
この処理が呼ばれたタイミングでモックインスタンスを注入しています。

doReturn

文法は以下のとおりです。

// 文法
Mockito.doReturn(戻り値).when(モックインスタンス).メソッド名(引数)

// 引数なし
Mockito.doReturn(3).when(subCalc).getValA();

// 引数あり
Mockito.doReturn(5).when(subCalc).getValC(anyInt(), anyInt());

anyInt()

getValC(int x, int y)は、見ての通り引数がint型です。
テストコードとしては、Mockito.doReturn(5)の部分で戻り値として5が返却されるようにモックしているので、getValC(int x, int y)にどんな数値を渡しても意味がないということになります。
こういう場面(どんな値を渡してもいいけど、型はint型になっている必要があるとき)は、anyInt()を使用します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です