You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Mockito编写测试覆盖控制器校验的异常处理器?

问题根源

直接调用Controller的方法会绕过Spring MVC的请求处理流程,@Valid注解的校验逻辑是由Spring MVC在处理HTTP请求时触发的,所以直接调用方法不会执行校验,自然进不了异常处理器。

调整方案

改用@WebMvcTest编写Controller测试,它会加载Spring MVC相关上下文(包括校验器、异常处理器),再通过MockMvc模拟HTTP请求,就能触发校验逻辑并走到异常处理器。

完整测试代码示例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(MyControlller.class)
class MyControlllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean // 模拟Controller依赖的HelloService
    private HelloService helloService;

    @Test
    void testValidationFailureTriggersExceptionHandler() throws Exception {
        // 构造不符合校验规则的请求体:dato为null
        String invalidRequestJson = "{\"dato\": null}";

        // 发送POST请求到目标接口,触发校验逻辑
        mockMvc.perform(post("/api/holamundo" + HelloApi.ENDPOINT_DESCUENTOS_PRODUCTOS_RESUMEN)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(invalidRequestJson))
                // 断言异常处理器返回的状态码,比如400 Bad Request
                .andExpect(status().isBadRequest());
    }
}
额外注意点
  • 原Controller构造函数存在类名错误:public DescuentoProductoController(HelloService helloService)应改为public MyControlller(HelloService helloService),否则实例化会报错。
  • 测试类中helloservice需修正为helloService(注意大小写),避免空指针异常。
  • 如果你的异常处理器自定义了响应内容,可以在andExpect中进一步断言响应体,确认异常处理器逻辑正确执行。

内容的提问来源于stack exchange,提问作者eros roses

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:52:08