1. 概述
在本篇教程中,我们聚焦于如何使用 Mockito 来配置方法调用时抛出异常。
如果你对 Mockito 还不熟悉,可以查看我们的 Mockito 系列文章。
下面是我们将使用的一个简单字典类:
class MyDictionary {
private Map<String, String> wordMap;
public void add(String word, String meaning) {
wordMap.put(word, meaning);
}
public String getMeaning(String word) {
return wordMap.get(word);
}
}
2. 非 void 返回类型的方法
✅ 如果方法有返回值(非 void),我们可以使用 when().thenThrow()
的方式来模拟异常:
@Test
void givenNonVoidReturnType_whenUsingWhenThen_thenExceptionIsThrown() {
MyDictionary dictMock = mock(MyDictionary.class);
when(dictMock.getMeaning(anyString())).thenThrow(NullPointerException.class);
assertThrows(NullPointerException.class, () -> dictMock.getMeaning("word"));
}
这段代码中,我们配置了 getMeaning()
方法在被调用时会抛出 NullPointerException
。由于该方法返回的是 String
类型,因此可以直接使用 when().thenThrow()
结构。
3. 返回类型为 void 的方法
⚠️ 如果方法没有返回值(即 void),就不能使用 when().thenThrow()
,因为 Java 编译器不允许将 void 方法写在括号表达式中。
此时应改用 doThrow().when()
的语法结构:
@Test
void givenVoidReturnType_whenUsingDoThrow_thenExceptionIsThrown() {
MyDictionary dictMock = mock(MyDictionary.class);
doThrow(IllegalStateException.class).when(dictMock)
.add(anyString(), anyString());
assertThrows(IllegalStateException.class, () -> dictMock.add("word", "meaning"));
}
上面的例子中,我们让 add()
方法在调用时抛出 IllegalStateException
。
4. 以对象形式传递异常
除了传入异常类之外,你也可以直接传入一个异常实例:
@Test
void givenNonVoidReturnType_whenUsingWhenThenAndExeceptionAsNewObject_thenExceptionIsThrown() {
MyDictionary dictMock = mock(MyDictionary.class);
when(dictMock.getMeaning(anyString())).thenThrow(new NullPointerException("Error occurred"));
assertThrows(NullPointerException.class, () -> dictMock.getMeaning("word"));
}
同样的方式也适用于 doThrow()
:
@Test
void givenNonVoidReturnType_whenUsingDoThrowAndExeceptionAsNewObject_thenExceptionIsThrown() {
MyDictionary dictMock = mock(MyDictionary.class);
doThrow(new IllegalStateException("Error occurred")).when(dictMock)
.add(anyString(), anyString());
assertThrows(IllegalStateException.class, () -> dictMock.add("word", "meaning"));
}
这种方式可以方便地自定义异常信息,非常适合调试和测试场景。
5. Spy 对象的异常模拟
✅ 使用 spy
时,也可以像 mock 一样配置其抛出异常的行为:
@Test
void givenSpyAndNonVoidReturnType_whenUsingWhenThen_thenExceptionIsThrown() {
MyDictionary dict = new MyDictionary();
MyDictionary spy = Mockito.spy(dict);
when(spy.getMeaning(anyString())).thenThrow(NullPointerException.class);
assertThrows(NullPointerException.class, () -> spy.getMeaning("word"));
}
注意:虽然 spy
是真实对象的代理,但在测试中仍然可以通过 when().thenThrow()
控制其行为。
6. 小结
在这篇文章中,我们学习了如何通过 Mockito 配置方法调用来抛出异常,包括:
- ✅ 非 void 方法使用
when().thenThrow()
- ⚠️ void 方法使用
doThrow().when()
- ✅ 可以传入异常类或异常实例
- ✅ spy 对象同样支持异常模拟
完整代码可以在 GitHub 上找到。