山崎屋の技術メモ

IT業界で働く中でテクノロジーを愛するSIerのシステムエンジニア👨‍💻 | AndroidとWebアプリの二刀流🧙‍♂️ | コードの裏にあるストーリーを綴るブログ執筆者✍️ | 日々進化するデジタル世界で学び続ける探究者🚀 | #TechLover #CodeArtisan、気になること、メモしておきたいことを書いていきます。

ユニットテストで 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



private

不可

4

×

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