山崎屋の技術メモ

IT業界で働く中で、気になること、メモしておきたいことを書いていきます。

ユニットテストで Mockito を使う

ユニットテストで使用する Mockito で Mock 化できるメソッド・できないメソッドをまとめて、実際のサンプルコードを記しておきます。

バージョン:

  • Java 11
  • junit 4.13
  • mockito 3.3.3

Maven も利用します。

公式ページ。
site.mockito.org

Mockito で Mock 化できるメソッド



No

static

スコープ

戻り値

モック化できる?

1



public

あり

不可

2



public

なし

不可

3

×

public

あり



4

×

public

なし



5



private

あり

不可

6



private

なし

不可

7

×

private

あり

不可

8

×

private

なし

不可

以外に少ないです。

パブリックで非 static なメソッドしか Mock 化できません。

final クラスも Mock 化できませんが javassist (バイナリ Class を書き換えるライブラリ)を使って無理やりやってしまうツワモノもいます。
Mockitoでfinalクラスをモック化 - kinjouj.github.io

Mock 化サンプル

準備

pom.xml に依存関係を追加します。全量載せておきます。

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.yyama</groupId>
	<artifactId>sample2</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>11</java.version>
		<maven.compiler.target>${java.version}</maven.compiler.target>
		<maven.compiler.source>${java.version}</maven.compiler.source>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.13</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>3.3.3</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

基本

今回は Mockito の mock() メソッドを使用します。このメソッドはクラスのインスタンスメソッドを丸ごと Mock 化します。

spy() メソッドでも Mock 化できます。こちらは指定したメソッドのみを Mock 化します。

非 static な public メソッドを Mock 化

戻り値なし
package org.yyama;

import static org.mockito.Mockito.mock;

import java.util.List;

import org.junit.Test;

public class TestSample {
	@Test
	public void test01() {
		List<String> mock = mock(List.class);
	}
}

これだけです。

これで mock 変数には Mock 化された List のインスタンスが格納され、public な 非 static メソッドは何もしないハリボテと化します。

次のように add メソッドで要素を追加しても何も実行されません。

	@Test
	public void test01() {
		List<String> mock = mock(List.class);
		
		mock.add("a");
		mock.add("b");
		mock.add("c");

		System.out.println(mock.size()); // → 0
	}
戻り値あり

前述したとおり public な 非static メソッドであれば戻り値の有無にかかわらず Mock 化されます。

	@Test
	public void test01() {
		List<String> mock = mock(List.class);

		System.out.println(mock.get(0)); // → null
		System.out.println(mock.get(1)); // → null
		
		List<String> list = Arrays.asList(new String[] { "a","b","c" });
		System.out.println(mock.equals(list)); // → false

		System.out.println(mock.size()); // → 0
	}

参照型を返すメソッドは null、
boolean を返すメソッドは false、
int を返すメソッドは 0 が返ってきます。

明示的に戻り値を指定する場合は when() と thenReturn() を使います。

package org.yyama;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.List;

import org.junit.Test;

public class TestSample {
	@Test
	public void test01() {
		List<String> mock = mock(List.class);

		when(mock.size()).thenReturn(5);
		System.out.println(mock.size()); // → 5
	}
}

 
doReturn() と when() を使って異なる書き方もできます。(やってることは上と同じです。)

package org.yyama;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

import java.util.List;

import org.junit.Test;

public class TestSample {
	@Test
	public void test01() {
		List<String> mock = mock(List.class);

		doReturn(5).when(mock).size();		
		System.out.println(mock.size()); // → 5
	}
}

まとめ

Mockito を使って Mock 化できるメソッドの種類、および mock() メソッドを使ったメソッドの Mock 化について簡単な利用方法を紹介しました。

private メソッドや static メソッド、final メソッドを Mock 化する場合は Mockit の弟分(兄貴分?)の Power Mock を使います。
github.com

本日はここまで!

JUnit の基本について書いた記事もぜひご覧ください。
www.shookuro.com

実践 JUnit ―達人プログラマーのユニットテスト技法

実践 JUnit ―達人プログラマーのユニットテスト技法