Java 使用Mockito从mock抛出已检查的异常
我试图让我的一个模拟对象在调用特定方法时抛出一个选中的异常。我正在尝试以下方法Java 使用Mockito从mock抛出已检查的异常,java,mocking,mockito,Java,Mocking,Mockito,我试图让我的一个模拟对象在调用特定方法时抛出一个选中的异常。我正在尝试以下方法 @Test(expectedExceptions = SomeException.class) public void throwCheckedException() { List<String> list = mock(List.class); when(list.get(0)).thenThrow(new SomeException()); String test = list
@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 {
}
查看,它们只使用RuntimeException
,难道不能用Mockito从模拟对象中抛出已检查的异常吗?检查Java API以了解更多信息。get(int index)
方法声明为仅抛出扩展了RuntimeException
的IndexOutOfBoundException
您试图告诉Mockito抛出一个异常SomeException()
,该异常对于该特定方法调用无效
进一步澄清。接口不提供从
get(int-index)
方法抛出选中的异常,这就是Mockito失败的原因。创建模拟列表时,Mockito将使用List类的定义来创建其模拟 当(list.get(0)).ThentThrow(new SomeException())与列表API中的方法签名不匹配,因为
get(int index)
方法不会抛出SomeException()
,所以Mockito失败
如果您真的想这样做,那么让Mockito抛出一个new RuntimeException()
,或者更好地抛出一个new ArrayIndexOutOfBoundsException()
,因为API指定这是唯一要抛出的有效异常。解决方法是使用一个方法
例如,下面使用BDDMockito
,可以工作(并且不会抛出MockitoException
,而是根据需要实际抛出选中的异常
):
given(someObj.someMethod(stringArg1)).willAnswer( invocation -> { throw new Exception("abc msg"); });
普通Mockito的等效方法是使用
doAnswer
方法Kotlin有一个解决方案:
given(myObject.myCall()).willAnswer {
throw IOException("Ooops")
}
给予从何而来
导入org.mockito.BDDMockito.given
注意,一般来说,只要在消息签名中声明了异常,Mockito就允许抛出已检查的异常。例如,给定
类BarException扩展异常{
//这是一个已检查的异常
}
接口Foo{
Bar frob()抛出异常
}
这样写是合法的:
Foo-Foo=mock(Foo.class);
when(foo.frob()).thenthow(BarException.class)
但是,如果抛出未在方法签名中声明的已检查异常,例如
类QuxException扩展异常{
//另一个已检查异常
}
Foo-Foo=mock(Foo.class);
when(foo.frob()).thenthow(QuxException.class)
Mockito将在运行时失败,并带有某种误导性的通用消息:
选中的异常对此方法无效!
无效:QuxException
这可能会让您相信,通常不支持选中的异常,但事实上,Mockito只是想告诉您,此选中的异常对该方法无效这对我在Kotlin的工作很有效:
when(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());
注意:抛出除exception()之外的任何已定义异常。当我的实际代码没有实际使用List时,您的答案也适用于该方法调用。我在嘲笑错误的方法。谢谢。额外:如果您使用的方法没有任何可丢弃项,Mocktio不会抱怨,但您也会得到Kotliners的此异常:Kotlin没有已检查的异常,因此您通常无法(在函数签名中)声明函数抛出异常。但是,您可以使用
Throws
注释对函数进行注释,使编译器生成与等效Java代码中声明Throws相同的字节码。有关更多详细信息,请参见[here]()。此检查自发布以来一直强制执行。相同的逻辑是否也适用于Scala?或者使用willAnswer(调用->{throw new Exception(“abc msg”);})当方法返回void
或使用when(someObj.someMethod(stringArg1)).thenAnswer(调用->{抛出新异常(“abc msg”);});非常好的解决方法,谢谢!对于希望(1)无缝地将其用作扩展函数的Kotliner,以及(2)能够传递像willThrow()
通常允许的多个参数的Kotliner,我已经编写了一个我正在寻找的,可以抛出除Exception
when(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());