mockito 的 when(...).thenthrow(...) 用于模拟方法抛出异常,支持运行时异常和检查型异常,可配合 verify 验证异常处理逻辑,并支持多次调用的不同行为组合。

在 Java 单元测试中,Mockito 的 when(...).thenThrow(...) 是专门用来模拟被测方法调用时抛出异常的常用方式,适用于验证异常处理逻辑、边界校验或失败路径是否正确执行。
基本用法:模拟指定方法抛出运行时异常
最常见场景是让 mock 对象的某个方法在被调用时直接抛出异常,比如 RuntimeException 或其子类(如 IllegalArgumentException):
- 确保目标方法已被 mock(通过
mock()或@Mock) - 使用
when(mockObject.method()).thenThrow(new XxxException()) - 注意:
thenThrow()接收的是异常实例或异常类(后者会触发默认构造)
示例:
UserService userService = mock(UserService.class);
when(userService.findById(123)).thenThrow(new RuntimeException("用户不存在"));
// 调用时会真实抛出该异常
assertThrows<font color="red">RuntimeException</font>(() -> userService.findById(123));
模拟检查型异常(Checked Exception)
若被模拟的方法声明抛出 checked exception(如 IOException),则 thenThrow() 必须传入该异常类型(不能只传运行时异常),否则编译不通过:
- 必须与方法签名中声明的异常类型兼容(即属于其 throws 列表中的类型或其子类)
- 可传异常实例,也可传异常类(Mockito 会尝试调用无参构造函数)
示例(假设 readFile() 声明 throws IOException):
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
FileReader reader = mock(FileReader.class);
when(reader.read()).thenThrow(new IOException("读取失败"));
// 或
when(reader.read()).thenThrow(IOException.class);
配合 verify 验证异常发生后的副作用
仅抛出异常还不够,常需验证异常后是否有其他行为(如日志记录、状态重置、回调触发等):
- 先用
thenThrow()设置异常路径 - 执行被测逻辑(通常会 catch 异常并做处理)
- 用
verify()检查依赖对象是否按预期被调用(如 logger.error 被调用一次)
示例:
Logger logger = mock(Logger.class);
OrderService service = mock(OrderService.class);
when(service.processOrder(any())).thenThrow(new PaymentFailedException());
orderController.handleOrder(order); // 内部捕获异常并调用 logger
verify(logger).error(eq("支付失败"), any(PaymentFailedException.class));
进阶:多次调用不同行为(含异常)
可用 thenReturn() / thenThrow() 链式组合,实现“前两次成功、第三次抛异常”等复杂模拟:
- 按调用顺序依次生效:
when(...).thenReturn(a).thenReturn(b).thenThrow(e) - 第 1 次调用返回
a,第 2 次返回b,第 3 次及之后抛出e
示例:
CacheService cache = mock(CacheService.class);
when(cache.get("key")).thenReturn("cached").thenReturn(null).thenThrow(new CacheUnavailableException());
System.out.println(cache.get("key")); // "cached"
System.out.println(cache.get("key")); // null
cache.get("key"); // 抛出 CacheUnavailableException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










