Spring MVC 3错误处理:JUnit 5+MockMvc测试异常场景失败求助
Spring MVC 异常测试失败问题排查与修复
问题1:测试用Controller实例未关联Mock服务
你的测试类存在两处关键错误:
@InjectMocks标注的是MyController,但实际待测试的Controller是CPCommonServiceController,类名不匹配导致Mock服务无法注入。- setup方法中手动新建
CPCommonServiceController实例,该实例独立于Mockito注入上下文,完全没用到你配置好的MockmyCommonService,因此when语句的异常模拟完全不生效,调用时会触发未初始化的真实服务逻辑或直接抛出未处理异常。
修复后的测试类代码:
public class CPCommonServiceControllerTest { @InjectMocks private CPCommonServiceController controller; // 修正类名,与目标Controller一致 @Mock private MyCommonService myCommonService; private MockMvc mockMvc; @BeforeEach public void setup() { MockitoAnnotations.openMocks(this); // 使用被@InjectMocks注入后的controller实例,而非新建实例 mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } @Test public void testDataThrowServiceException() throws Exception { when(myCommonService.getData()) .thenThrow(new ServiceException("测试异常")); // 建议实例化具体异常对象,而非仅指定类 // 若未配置全局异常处理器,默认返回500状态码;后续配置异常映射后可改为is4xxClientError mockMvc.perform(get("/data").header("Accept", "application/json")) // 需添加Controller要求的请求头 .andExpect(MockMvcResultMatchers.status().is5xxServerError()); } }
问题2:未配置异常转状态码的处理逻辑
Controller抛出ServiceException后,Spring MVC默认不会将自定义异常映射为4xx客户端错误,而是返回500内部服务器错误。若业务需求是将该异常转为4xx状态码,需添加全局异常处理器:
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ServiceException.class) @ResponseBody public ResponseEntity<String> handleServiceException(ServiceException e) { // 根据业务场景选择对应4xx状态码,如400 Bad Request return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); } }
添加该处理器后,测试中的is4xxClientError()断言即可正常通过。
额外注意:Controller的@RequestMapping要求了headers = "Accept=application/json",测试时必须在请求中添加对应头信息,否则会因请求不匹配映射条件返回404。
内容的提问来源于stack exchange,提问作者Nidhi257
相关产品推荐
相关产品推荐

