自動テストツール JUnit Mockito/PowerMockito
目次
Mockitoとは
Publicメソッドのテスト、Publicメソッド内のメソッドのMock化が可能
PowerMockitoとは
Privateメソッド、Staticメソッドのテストが可能なMockitoの拡張版
Powermockitoを使用する場合もMockitoは使用する。
Mock化、Spy化の手順がMockitoと異なる。
ここではPowerMockitoを使用する前提での手順を記載する
Mock
Mockとは
本番環境で外部のサーバに接続する様な処理に対して、
TEST環境では外部サーバに接続できず必ず失敗してしまうが、
その処理が成功したとしてテストを行いたい場合に使用。
外部接続処理をMockと呼ぶ
Mock化
通常
@Mock
praivete TestClass mock;
newできない場合
Mockアノテーションは自動的にnewされてインスタンスが生成される為、newできない場合は失敗する
クラス内で外部を参照するstatic変数を宣言している等
その場合はクラス内のstatic変数を先にmock化する必要あり
TestClassクラス内のstatic変数を先にmock化する処理
TestClass mock = PowerMockito.mock(new TestClass());
Spyとは
テスト対象メソッド自体は実行、メソッド内の一部をMock化する場合のMock
テストクラスに記述
@RunWith(PowerMockRunner.class)
@PrepareForTest({TestClass.class, 他.class})
public class AppTest { ~
Spy化
通常
@Spy
private TestClass spy = new TestClass();
TestClassのnewができない場合
TestClassへの事前処理
TestClass mock = PowerMockito.spy(new TestClass());
Publicメソッド
Mockito.doReturn(戻り値).when(mock).メソッド名(メソッド引数);
Publicメソッド(Void型)
Mockito.doNothing().when(mock).メソッド名(メソッド引数);
Mockito.doNothing().when(mock).メソッド名(Mockito.any(クラス名.class));
インスタンスをMockで取得
テスト対象のメソッド内等でインスタンス化が実行され、インスタンスメソッドを呼ぶ処理をテストする場合
PowerMockito.whenNew(クラス名.class).withNoArguments().thenReturn(mock);
PowerMockito.whenNew(クラス名.class).withArguments(anyString()).thenReturn(mock);
PowerMockito.whenNew(クラス名.class).withArguments(anyInt()).thenReturn(mock);
Privateメソッド
PowerMockito.doNothing().when(mock,”メソッド名”, メソッド引数);
PowerMockito.doReturn(戻り値).when(mock,”メソッド名”, メソッド引数);
Staticメソッド
テストクラスに記述
@RunWith(PowerMockRunner.class)
@PrepareForTest({Staticメソッドのクラス.class, 他.class})
public class AppTest { ~
PowerMockito.mockStatic(Staticメソッドのクラス.class);
PowerMockito.when(Staticメソッド()).thenReturn(Staticメソッド戻り値);
Static&Privateメソッド
テストクラスに記述
@RunWith(PowerMockRunner.class)
@PrepareForTest({Staticメソッドのクラス.class, 他.class})
public class AppTest { ~
PowerMockito.spy(Staticクラス.class);
PowerMockito.doReturn(戻り値).when(Staticクラス.class, “メソッド名”, 引数);
Setter無しのPrivateフィールド
インスタンスをMock化 「インスタンスをMockで取得」参照
PowerMockito.whenNew(クラス名.class).withNoArguments().thenReturn(mock);
MockのPrivateフィールド(Setter無し)に値をセット
Whitebox.setInternalState(mock, “privateフィールド名”, 設定値);
Mockの挙動も指定
PowerMockito.doAnswer(invocation -> {
メソッド内部の挙動
return Void.TYPE;
}).when(mock, “メソッド名”, メソッド引数);
Mock引数の簡略化
Mockito.Any(String.class)
Mockito.Any(List.class)
List<Test>等の場合
テスト実行
mockはスパイ
Publicメソッドの実行
戻り値 = mock.メソッド名(メソッド引数);
Privateメソッドの実行
通常
java.lang.reflect
Method method = TestClass.class.getDeclaredMethod(“プライベートメソッド名”, メソッド引数のクラス.class);
method.setAccessible(true);
戻り値 = method.invoke(mock, メソッド引数);
テスト対象メソッドの中のプライベートメソッドを更にMock化する場合
Whitebox.invokeMethod(mock, “プライベートメソッド名”, メソッド引数);
Getter無しのPrivateフィールドの値取得
java.lang.reflect
Test test = new Test();
Field field = test.getClass().getDeclaredField(“privateフィールド名”);
field.setAccessible(true);
“privateフィールド名”の値を取得
String actual = String.valueOf(field.get(test));
テスト結果の検証
値の比較
import static org.hamcrest.CoreMatchers.is;
Assert.assertThat(actualValue, is(expectValue));
リストの比較
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.samePropertyValuesAs;
Assert.assertThat(actualList, is(samePropertyValuesAs(expectList));
publicメソッドの実行回数
Mockito.verify(mock, times(0)).メソッド名(メソッド引数);
Mockito.verify(mock, times(1)).メソッド名(メソッド引数);
Privateメソッドの実行回数
PowerMockito.verifyPrivate(mock, times(0)).invoke(“メソッド名”, メソッド引数);
PowerMockito.verifyPrivate(mock, times(1)).invoke(“メソッド名”, メソッド引数);
失敗
try {
例外が発生する事を検証する場合
mock.メソッド();
処理されなければOK
Assert.fail();
} catch(Exception e) {
~
}