You need to enable JavaScript to run this app. Kotlin开发中如何测试控制器抛出指定自定义异常?
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin开发中如何测试控制器抛出指定自定义异常?

MockMvc场景下校验自定义异常抛出的实现方案

针对你已有的测试基础,核心不需要改动原有接口请求逻辑,只需要在原有断言链上扩展对应校验逻辑即可,根据项目的异常处理配置不同,有两种可直接落地的写法:

1. 通用适配写法(适配绝大多数带全局异常处理器的项目)

不管你有没有配置全局@ControllerAdvice,都可以通过MockMvc内置的resolvedException属性直接拿到请求执行过程中抛出的真实异常对象,直接做类型校验,不需要依赖响应体的字段约定:

  • 若测试类已引入AssertJ断言依赖可跳过依赖配置环节
  • 在原有的断言链上追加异常类型断言即可,示例代码:
@Test
fun `校验传入无效ISO编码时抛出InvalidIsoCodeException`() {
    mockMvc.perform(get("/countries/UA"))
        .andDo(print())
        .andExpect(status().is4xxClientError)
        // 直接校验请求解析过程中捕获到的异常就是目标自定义类型
        .andExpect {
            assertThat(it.resolvedException).isInstanceOf(InvalidIsoCodeException::class.java)
        }
}

说明:resolvedException是MockMvc在执行请求时,从Spring MVC的DispatcherServlet捕获到的全链路异常对象,哪怕后续被全局异常处理器转换成了标准错误响应,这个属性也会保留原始的异常实例,完全可以满足你校验自定义异常抛出的需求。

2. 符合全局响应规范的扩展校验

如果你们的项目约定全局异常处理器会把异常类型、错误信息写入统一的响应体结构(比如RESTful API的标准错误格式),还可以直接校验响应体内容来匹配生产环境的实际返回行为:

@Test
fun `校验传入无效ISO编码时抛出InvalidIsoCodeException`() {
    mockMvc.perform(get("/countries/UA"))
        .andDo(print())
        .andExpect(status().is4xxClientError)
        // 校验响应体中记录的异常标识和自定义异常匹配
        .andExpect(jsonPath("$.errorType").value(InvalidIsoCodeException::class.java.simpleName))
        // 可同步校验异常携带的具体业务提示
        .andExpect(jsonPath("$.message").value("国家ISO编码不符合规则"))
}

常见注意点

  • 不需要为了测试刻意关闭全局异常处理器,否则测试验证的行为和线上运行逻辑会出现偏差
  • 不要通过手动try-catch的方式捕获MockMvc.perform抛出的异常,绝大多数场景下Spring MVC会把异常消化在请求链路内部,这种方式会出现捕获不到异常的无效测试

内容的提问来源于stack exchange,提问作者Y. Baranov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 01:24:03