Spring Boot全局异常测试核心是验证@RestControllerAdvice能否正确拦截Controller抛出的特定异常并返回预期响应,包括状态码、code和message字段;推荐使用MockMvc集成测试,覆盖参数校验异常、业务异常、系统异常兜底及处理器单元测试。

Spring Boot 全局异常的测试用例,核心是验证:当 Controller 抛出特定异常时,@RestControllerAdvice 是否能正确拦截,并返回预期格式的响应(如 Result> 或 ApiResult>),且状态码、code 字段、message 字段均符合设计。
MockMvc 驱动的集成测试(推荐)
这是最贴近真实请求链路的方式,不启动完整容器,但能模拟 HTTP 调用并断言响应体和状态码。
- 引入
spring-boot-starter-test(已默认包含 MockMvc) - 用
@AutoConfigureMockMvc启用 MockMvc 自动配置 - 注入
MockMvc实例,调用perform()发起请求 - 用
andExpect(status().isXXX())断言 HTTP 状态码 - 用
andExpect(jsonPath("$.code").value(400))和andExpect(jsonPath("$.message").value("用户名不能为空"))断言 JSON 响应字段
示例:测试参数校验异常(MethodArgumentNotValidException)
(假设你有一个接收 @Valid @RequestBody User user 的 POST 接口)
@Test
void whenInvalidUser_thenReturns400() throws Exception {
String invalidJson = "{\"username\":\"\",\"age\":-5}";
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(invalidJson))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.code").value(400))
.andExpect(jsonPath("$.message").value("username: 用户名不能为空, age: 年龄不能为负数"));
}
业务异常的针对性测试
直接在测试中抛出你的自定义异常(如 BusinessException),验证其是否被 @ExceptionHandler(BusinessException.class) 捕获。
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 在 Controller 方法中手动 throw 新的
BusinessException(10001, "用户不存在") - 或使用 Mockito 对 Service 层打桩,使其抛出该异常,再调用 Controller
- 断言返回的
code是 10001,message是 "用户不存在"
示例:
@Test
void whenBusinessExceptionThrown_thenReturnsCustomCodeAndMsg() throws Exception {
mockMvc.perform(get("/api/users/999"))
.andExpect(status().isOk()) // BusinessException 默认走 200,由 code 字段标识业务失败
.andExpect(jsonPath("$.code").value(10001))
.andExpect(jsonPath("$.message").value("用户不存在"));
}
系统异常兜底测试
验证未被显式捕获的运行时异常(如 RuntimeException)是否落入通用处理器,返回 500 及统一错误信息。
- 让某个接口直接 throw new RuntimeException("test")
- 断言状态码为 500,且响应体中
code为 500、message包含“系统内部错误”等兜底文案 - 注意:生产环境建议记录日志但不暴露堆栈,测试中可额外验证日志是否输出
单元测试异常处理器本身(可选进阶)
将 GlobalExceptionHandler 当作普通 POJO 测试,不依赖 Web 环境:
- 手动 new 出处理器实例
- 调用其
handleBusiness(new BusinessException(10002, "用户已存在"))方法 - 断言返回的
ApiResult对象的code、message、data字段是否正确 - 优点:执行快、隔离性强;缺点:无法覆盖 Spring 的 AOP 拦截逻辑










