如何用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
相关产品推荐
相关产品推荐

