Mockitoでモックからチェックされた例外をスローする


173

特定のメソッドが呼び出されたときに、モックされたオブジェクトの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でモックオブジェクトからチェックされた例外をスローすることはできませんか?

回答:


221

Java APIのリストを確認してください。メソッドは、スローするように宣言されて延びているが。 Mockitoに、特定のメソッド呼び出しによってスローされるのに有効ない例外をスローするように伝えようとしています
get(int index)IndexOutOfBoundExceptionRuntimeException
SomeException()

さらに明確にするために。リストインターフェースからスローされるチェック例外を提供しない方法とMockitoが失敗した理由です。モックリスト を作成すると、MockitoはList .class の定義を使用してモックを作成します。
get(int index)

メソッドでスローしないため、Mockitoが失敗するため、when(list.get(0)).thenThrow(new SomeException()) 指定している動作がリストAPIのメソッドシグネチャと一致get(int index)しませんSomeException()

これを本当に実行したい場合は、APIがそれがスローされる唯一の有効な例外であることを指定してnew RuntimeException()いるnew ArrayIndexOutOfBoundsException()ので、Mockitoにa またはさらに良いaをスローさせます。


私の実際のコードは実際にはListを使用していませんが、あなたの答えはそのメソッド呼び出しにも適用されます。私は間違った方法をあざけっていました。ありがとうございました。
Arthur Maltson、2009

2
余分:MocktioはdoThrowやスロー可能オブジェクトのないメソッドの場合は文句を言いませんが、この例外も発生します
dwana

8
Kotlinersの場合:Kotlinは例外をチェックしていないため、通常、関数が例外をスローすることを関数シグネチャで宣言することはできません。ただし、関数にThrows注釈を付けて、同等のJavaコードでスローを宣言するのと同じバイトコードをコンパイラーに生成させることができます。詳細については、[ここ](kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/…)を参照してください。
Javad Sadeqzadeh 2017年

1
このチェックは、Mockito 2.11.0(2.10.3を参照)のリリース以降に適用されます。
JJD 2018年

106

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

たとえば、次のコードは、次を使用して動作します(MockitoException実際には、スローされませんが、実際には、Exception必要に応じてチェックをスローします)BDDMockito

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

普通のMockitoと同等のdoAnswer方法を使用します


9
またはwillAnswer( invocation -> { throw new Exception("abc msg"); }).given(someObj).someMethod(stringArg1);、メソッドが戻るときに使用しますvoid
ジュリアンクロネッグ

9
またはwhen(someObj.someMethod(stringArg1))。thenAnswer(invocation-> {throw new Exception( "abc msg");});を使用します。
Dmitri Algazin

素晴らしい回避策、ありがとう!(1)それをシームレスに拡張関数として使用し、(2)willThrow()通常許可されているようにいくつかの引数を渡すことができるKotlinersのために、Gist
David Ferrand

2
またはdoAnswerからnhaarman.mockitokotlin2
HMAC

6

一般に、Mockito では、例外がメッセージ署名で宣言されている限り、チェックされた例外をスローすることできます。たとえば、

class BarException extends Exception {
  // this is a checked exception
}

interface Foo {
  Bar frob() throws BarException
}

書くことは合法です:

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(BarException.class)

ただし、メソッドシグネチャで宣言されていないチェック済み例外をスローすると、たとえば

class QuxException extends Exception {
  // a different checked exception
}

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(QuxException.class)

Mockitoは実行時に失敗し、やや誤解を招くような一般的なメッセージが表示されます。

Checked exception is invalid for this method!
Invalid: QuxException

これにより、チェックされた例外は一般的にサポートされていないと思われるかもしれませんが、実際、Mockitoはこのチェックされた例外がこのメソッドに対して有効ないことを伝えようとしているだけです。


5

Kotlinによる解決策があります:

given(myObject.myCall()).willAnswer {
    throw IOException("Ooops")
}

所与はどこから来たのか

import org.mockito.BDDMockito.given


1

これは私にとってコトリンで機能します:

when(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());

注:Exception()以外の定義済みの例外をスローします


私が探していたものだけが例外以外の例外をスローする可能性がありますException
Naeem Sarfraz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.