使用Mockito从mock中抛出checked异常

我试图让我的一个模拟对象抛出一个checked Exception当一个特定的方法被调用。我正在尝试以下方法。

@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

看看5文档,他们只使用RuntimeException,难道不能用Mockito从一个模拟对象抛出受控异常吗?

337677 次浏览

检查列表的Java API get(int index)方法被声明为只抛出扩展了RuntimeExceptionIndexOutOfBoundException 你试图告诉Mockito抛出一个异常SomeException(),即由该特定方法调用抛出是无效的.

为了进一步澄清 列表接口没有提供由get(int index)方法抛出的受控异常,这就是Mockito失败的原因 当你创建嘲笑列表时,Mockito将使用List的定义.class来创建它的mock。< / p >

你用when(list.get(0)).thenThrow(new SomeException()) 与列表API中的方法签名不匹配指定的行为,因为__ABC1方法不会抛出SomeException()所以Mockito失败。

如果你真的想这样做,那么让Mockito抛出一个new RuntimeException(),或者更好的是抛出一个new ArrayIndexOutOfBoundsException(),因为API指定这是唯一要抛出的有效异常。

一个变通方法是使用willAnswer()方法。

例如,使用BDDMockito可以工作(并且不会抛出MockitoException,但实际上会抛出此处要求的经过检查的Exception):

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

普通Mockito的等效函数将使用doAnswer方法

Kotlin有一个解决方案:

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

given从何而来

进口org.mockito.BDDMockito.given

注意,在一般情况下,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只是试图告诉你受控异常是无效的对于这个方法

这适用于我在Kotlin:

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

注意:抛出除exception()以外的任何定义异常