ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

@Mocked/@Capturingの違い

@Capturing テスト実行の間にJVMによってロードされる追加のクラスについてもモックする
@Mocked テスト実行の間にJVMによってロードされる追加のクラスはモックしない

テスト対象クラス(Hello.java

import java.io.File;
import java.io.FileFilter;


public class Hello {
	public static String helloStatic() {
		return "helloStatic()";
	}
	
	public String helloInstance1() {
		return "helloInstance1";
	}

	public String helloInstance2() {
		return "helloInstance2";
	}
	
	public File[] getFiles() {
		// このファイルフィルタは、このメソッドが呼ばれると動的にロードされる
		return new File(".").listFiles(new FileFilter() {
			public boolean accept(File file) {
				return true;
			}
		});
	}
}

テストクラス(HelloTest.java

import java.io.File;

import java.io.FileFilter;

import mockit.Capturing;
import mockit.Expectations;
import mockit.Mocked;
import mockit.integration.junit4.JMockit;

import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

// @Capturingを調べるサンプル
@RunWith(JMockit.class)
public class CapturingTest2 {
	@Test
	public void testHelloMocked(@Mocked FileFilter filter) {
		// 記録フェーズ
		new Expectations() {{
			// filterはリプレイフェーズでロードされるので、ここではモックできない。
			filter.accept((java.io.File)any); returns(true, true, false);
		}};
		
		// リプレイフェーズ
		Hello hello = new Hello();
		File[] files = hello.getFiles();
		
		// 検証フェーズ
		for(File f : files) {
			System.out.println(f);
		}
		assertThat(files.length, is(2));
	}

	@Test
	public void testHelloCapturing(@Capturing FileFilter filter) {
		// 記録フェーズ
		new Expectations() {{
			// filterはリプレイフェーズでロードされるが、@Capturing指定しているのでここでモックできる。
			filter.accept((java.io.File)any); returns(true, true, false);
		}};
		
		// リプレイフェーズ
		Hello hello = new Hello();
		File[] files = hello.getFiles();
		
		// 検証フェーズ
		for(File f : files) {
			System.out.println(f);
		}
		assertThat(files.length, is(2));
	}
}