使用 Mockito 从模拟中抛出已检查的异常

2022-08-31 05:24:17

我正在尝试让一个模拟对象在调用特定方法时引发已检查的异常。我正在尝试以下操作。

@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文档,他们只使用,是不是可以用Mockito从模拟对象中抛出检查的异常?RuntimeException


答案 1

检查 Java API 中的列表
该方法被声明为仅抛出哪个扩展。
您正在尝试告诉 Mockito 抛出一个无效的异常,该异常由该特定方法调用引发get(int index)IndexOutOfBoundExceptionRuntimeExceptionSomeException()

进一步澄清。
List 接口不提供从该方法引发的已检查异常,这就是 Mockito 失败的原因。
创建模拟列表时,Mockito 将使用 List.class 的定义来创建其模拟。get(int index)

您使用 指定的行为与 List API 中的方法签名不匹配,因为 get(int index) 方法不会引发 SomeException() 因此 Mockito 失败。when(list.get(0)).thenThrow(new SomeException())

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


答案 2

解决方法是使用 willAnswer() 方法。

例如,以下工作(并且不抛出一个,但实际上按照此处的要求抛出一个检查),使用:MockitoExceptionExceptionBDDMockito

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

普通Mockito的等效物将使用该方法doAnswer


推荐