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

Spring Boot控制器异常测试问题:Mock异常未被正确捕获返回200

问题分析与解决方案

核心问题排查

1. 异常类型不匹配

测试用例中抛出的是CustomNotFoundException,但你的@RestControllerAdvice只处理CarNotFoundException,两者完全不匹配,这是异常未被捕获的直接原因。

2. 请求路径不匹配

控制器的GetMapping路径是/cars/{id},但测试请求的是/api/cars/98776,路径前缀/api未在控制器中定义,导致请求没命中目标接口,无法触发后续异常逻辑。

3. Mock条件不匹配

测试中Mock的是service.getCar(CONSTANT.CAR_ID),但实际请求的路径参数是98776,如果CONSTANT.CAR_ID不等于"98776",Mock的抛出异常逻辑不会生效,接口会返回默认200(Mock默认返回null,ResponseEntity.ok(null)依然是200状态)。

4. 上下文配置冗余

@WebMvcTest已自动加载控制器、异常处理器等Web层组件,额外添加@ContextConfiguration(classes={MyApplication.class})会加载整个应用上下文,可能导致组件扫描异常,覆盖@WebMvcTest的默认配置。

修正后的代码示例

修正测试用例

@WebMvcTest(MyController.class)
// 移除冗余的@ContextConfiguration,仅加载Web层组件
public class ControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private Service service;

    private static final String TEST_CAR_ID = "98776";

    @Test
    void should_return_404_not_found() throws Exception {
        // 确保Mock参数与请求路径参数一致
        when(this.service.getCar(TEST_CAR_ID))
                // 抛出与异常处理器匹配的异常类型
                .thenThrow(new CarNotFoundException("not Found"));

        // 请求路径匹配控制器定义的路径
        mockMvc.perform(get("/cars/{id}", TEST_CAR_ID)
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isNotFound());
    }
}

若需/api前缀,修正控制器路径

如果应用确实需要/api前缀,在控制器类上添加@RequestMapping("/api"):

@RestController
@RequestMapping("/api")
public class MyController {
    private final Service service;

    @GetMapping(value = "/cars/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<Cars>> getCar(@PathVariable final String carId) {
        var car = this.service.getCar(carId);
        return ResponseEntity.ok(car);
    }
}

确保异常处理器被扫描

若Mapper类未被自动扫描,可在@WebMvcTest中显式指定包含该类:

@WebMvcTest(
    controllers = MyController.class,
    includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = Mapper.class)
)
public class ControllerTest {
    // ... 测试代码
}

验证步骤

  1. 确认Mock参数与请求参数完全一致
  2. 确认抛出的异常类型与@ExceptionHandler处理的类型匹配
  3. 检查请求路径与控制器路径一致
  4. 确保异常处理器类被Spring上下文正确加载

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:31:19