assertThrows是最推荐的异常断言方式,可获取异常实例校验类型、消息、错误码及嵌套原因,并支持与Mockito配合模拟依赖异常。

用 assertThrows 是最直接、最推荐的方式,它既能确认异常被抛出,又能拿到异常对象做进一步校验,比旧版 @Test(expected = ...) 更安全、更灵活。
断言指定异常类型并获取实例
核心是传入异常类和待执行代码块,方法返回实际抛出的异常对象,供后续验证:
- 写法:
MyException e = assertThrows(MyException.class, () -> methodThatThrows()); - 如果没抛出该类型异常,或根本没抛异常,测试直接失败
- 返回值非 null,可放心调用
e.getMessage()、e.getErrorCode()等方法
校验异常消息和自定义字段
只检查类型不够严谨,通常要连带验证提示文案或业务字段:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 断言完整消息:
assertEquals("余额不足:200.0", e.getMessage()); - 断言错误码(假设自定义异常有
getErrorCode()):assertEquals("ERR_001", e.getErrorCode()); - 模糊匹配消息内容:
assertTrue(e.getMessage().contains("用户名")); - 避免空指针:先
assertNotNull(e.getMessage()),再校验内容
处理嵌套异常(getCause)
当目标异常是包装了底层原因的“外层异常”时,需检查其 getCause():
立即学习“Java免费学习笔记(深入)”;
- 必须先保存异常实例,否则无法链式调用:
IllegalArgumentException ex = assertThrows(...); -
getCause()可能为 null,使用前建议判空或用 AssertJ 链式断言更稳妥 - 校验 cause 类型:
assertInstanceOf(NullPointerException.class, ex.getCause()); - 校验 cause 消息:
assertNotNull(ex.getCause()); assertTrue(ex.getCause().getMessage().contains("email"));
配合 Mockito 模拟异常场景
真实业务中,异常常来自依赖服务,需要用 mock 触发:
- 对 void 方法抛异常:
doThrow(new BusinessException("订单不存在")).when(orderService).cancelOrder("123"); - 对有返回值方法抛异常:
when(paymentService.pay(any())).thenThrow(new BusinessException("支付超时")); - 之后仍用
assertThrows断言被测方法是否如预期抛出对应异常 - 注意:不能对 void 方法用
when(...).thenThrow(...),编译通过但运行时报错

















