web-dev-qa-db-ja.com

Mockitoでモックからチェック済み例外をスローする

特定のメソッドが呼び出されたときに、モックされたオブジェクトの1つにチェック済みの例外をスローさせようとしています。私は次を試みています。

@Test(expectedExceptions = SomeException.class)
public void throwCheckedException() {
    List<String> list = mock(List.class);
    when(list.get(0)).thenThrow(new SomeException());
    String test = list.get(0);
}

public class SomeException extends Exception {
}

ただし、次のエラーが発生します。

org.testng.TestException: 
Expected exception com.testing.MockitoCheckedExceptions$SomeException but got org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!
Invalid: com.testing.MockitoCheckedExceptions$SomeException

Mockitoドキュメント を見ると、彼らはRuntimeExceptionのみを使用していますが、Mockitoを使用してモックオブジェクトからチェック済み例外をスローすることはできませんか?

129
Arthur Maltson

Java AP​​Iで List を確認してください。 get(int)メソッドは、RuntimeExceptionを拡張するIndexOutOfBoundExceptionのみをスローするように宣言されています。 Mockitoに、その特定のメソッド呼び出しによってスローされるのに無効な例外をスローするように指示しようとしています。

さらに明確にするために。 Listインターフェースは、get()メソッドからスローされるチェック済み例外を提供しません。そのため、Mockitoは失敗します。模擬リストを作成すると、MockitoはList.classの定義を使用して模擬を作成します。 when(list.get(0)).thenThrow(new SomeException())で指定する動作は、List.classのメソッドシグネチャと一致しないため、Mockitoは失敗します。本当にこれを行いたい場合は、APIがスローされる唯一の有効な例外であるとAPIが指定しているので、Mockitoにnew RuntimeException()をスローさせるか、さらに良いのはnew ArrayIndexOutOfBoundsException()をスローさせます。

177
John Engelman

回避策は、 willAnswer() メソッドを使用することです。

たとえば、MockitoExceptionを使用すると、次のように動作します(Exceptionはスローしませんが、実際には、必要に応じてチェック済みBDDMockitoをスローします)。

given(someObj.someMethod(stringArg1)).willAnswer( invocation -> { throw new Exception("abc msg"); });

プレーンMockitoに相当するものはdoAnswerメソッドを使用します

59
Deepak