環境
- Java 1.8.0_282
- Spring Boot 2.4.9
概要
Spring Bootのテストコードで、privateメソッドのException発生をテストしたところ、全てInvocationTargetException
となってしまうので、その対策方法について調べた。
テスト対象のクラス
以下のメソッドでは引数にListが渡され最初の要素を取得しているが、もし空のListが渡された場合、存在しない要素を取得しようとすることになるので、ArrayIndexOutOfBoundsException
が発生することを期待する。
テスト対象のクラス
public class SampleService {
// Listの最初の要素を取得する
private Long samplePrivateMethod(List<Long> array) throws ArrayIndexOutOfBoundsException {
return array.get(0);
}
}
テストコード
前述の通り、ArrayIndexOutOfBoundsException
が発生するかをテストしたい。しかしprivateメソッドをテストする場合、assertThrows
でチェックするとInvocationTargetException
を拾ってしまう。
そのため、まずassertThrowsでInvocationTargetException
が発生することをチェックし、その戻り値の中にArrayIndexOutOfBoundsException
があるかどうかをチェックするという方法を取る。
テストコード
@ExtendWith(MockitoExtension.class)
public class SampleServiceTest {
private SampleService sampleService;
@Test
public void sampleTest() throws Exception {
// テスト対象のクラスとprivateメソッドと引数の型(List.class)
Method method = SampleService.class.getDeclaredMethod("samplePrivateMethod", List.class);
// privateメソッドの実行を許可
method.setAccessible(true);
// samplePrivateMethodの引数にArrays.asList()、つまり空のListを渡す。
// privateメソッドを実行すると、method.invoke()のExceptionであるInvocationTargetExceptionが発生する。
InvocationTargetException e = assertThrows(InvocationTargetException.class, () -> method.invoke(sampleService, Arrays.asList()));
// InvocationTargetExceptionの戻り値の中に、ArrayIndexOutOfBoundsException.classがあるかどうかでチェックする
assertEquals(ArrayIndexOutOfBoundsException.class, e.getCause().getClass());
}
}
以上