精准断言自定义异常需用assertthrows获取异常实例,再逐项验证类型、消息及errorcode等字段;避免模糊匹配和链式空指针,支持嵌套异常和构造逻辑校验,配合assertj可提升可读性与健壮性。

在 Java 单元测试中精准断言自定义异常,核心是用 assertThrows 捕获异常实例,再对其类型、消息、字段(如 errorCode、httpStatus)等做逐项验证。不靠猜测,也不依赖模糊匹配,而是把异常当作普通对象来断言。
用 assertThrows 拿到异常对象再校验
JUnit 5 的 assertThrows 不仅能确认异常被抛出,还会返回该异常的实例,这是“精准”的前提:
- 必须传 Lambda 表达式(如
() -> service.doSomething()),不能直接调用方法,否则异常会提前中断测试 - 返回值要赋给变量,比如
MyException e = assertThrows(MyException.class, ...) - 后续所有断言都基于这个
e,而不是靠try-catch或@Test(expected = ...)这类黑盒方式
校验自定义异常的 errorCode 和 message
如果自定义异常有业务字段(如 errorCode、details、httpStatus),就分别断言:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
assertEquals("ERR_002", e.getErrorCode())assertEquals("参数不能为空", e.getMessage())-
assertNotNull(e.getDetails()),再进一步断言细节内容 - 避免链式调用空指针:不用
e.getMessage().contains("xxx"),改用assertTrue(e.getMessage() != null && e.getMessage().contains("xxx"))或分两步断言
处理嵌套异常和构造逻辑
有些自定义异常封装了 cause,或在构造时做了状态初始化,测试时需覆盖这些路径:
- 断言根本原因:
assertThat(e.getCause()).isInstanceOf(SQLException.class) - 验证异常是否携带原始参数(如 ID、时间戳):
assertEquals("U-123", e.getUserId()) - 若异常由工厂方法或 Builder 构建,测试也要覆盖该构建路径,确保字段赋值无遗漏
配合 AssertJ 提升可读性和健壮性
原生 Assertions 足够用,但 AssertJ 的流式写法更直观、失败提示更清晰:
- 导入:
import static org.assertj.core.api.Assertions.*; - 写法:
assertThatThrownBy(() -> service.process(invalidInput)) .isInstanceOf(MyException.class) .hasMessage("参数格式错误") .extracting("errorCode").isEqualTo("ERR_003"); - 优势:天然支持字段提取、嵌套断言、软断言(多个校验失败后统一报错)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










