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());