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

Spring Boot使用@WebMvcTest测试Controller时期望200却返回404

问题根本原因

你在测试类上额外添加的@ContextConfiguration注解覆盖了@WebMvcTest默认的上下文加载逻辑:

  • @WebMvcTest默认会自动注册你指定的TravelController到MVC上下文,同时只会加载Web层相关的Bean
  • 你手动配置的@ContextConfiguration仅指定了Mapper相关的类,没有包含TravelController,导致控制器没有被Spring托管,对应的/travels接口也没有完成注册,请求自然返回404
  • 你移除Mapper后不需要再添加@ContextConfiguration注解,@WebMvcTest的默认逻辑生效,控制器正常注册,测试就能通过。

解决方案

方案1:移除@ContextConfiguration,用MockBean处理Mapper(Web层单元测试最优)

Web层单元测试不需要依赖真实的Mapper实现,直接Mock Mapper的返回结果即可:

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = TravelController.class)
class TravelControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private TravelService travelService;
  // 将Mapper也改为MockBean
  @MockBean
  private TravelOutputDtoMapper travelOutputDtoMapper;

  @Test
  void testGetAll() throws Exception {
      List<Travel> travels = mockTravelList();
      List<TravelOutputDto> mockDtoList = // 构造模拟的DTO返回结果
      Mockito.when(travelService.getAll()).thenReturn(travels);
      // 补充Mapper的Mock逻辑
      Mockito.when(travelOutputDtoMapper.travelToTravelOutputDto(any(Travel.class)))
              .thenAnswer(invocation -> {
                  Travel travel = invocation.getArgument(0);
                  return new TravelOutputDto(travel.getFrom().getCode(), travel.getTo().getCode());
              });

      mockMvc.perform(get("/travels"))
              .andExpect(status().isOk());
  }

  private List<Travel> mockTravelList() {
    // 原有模拟逻辑保持不变
  }
}

方案2:保留真实Mapper实现,补充控制器到上下文配置

如果你的测试需要用到真实的MapStruct Mapper实现,只需把TravelController也加入@ContextConfiguration的类列表即可:

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = TravelController.class)
@ContextConfiguration(classes = {
    TravelController.class, // 补充控制器类到上下文
    TravelOutputDtoMapper.class,
    TravelOutputDtoMapperImpl.class
})
class TravelControllerTest {
  // 其余代码和你原有逻辑保持一致即可
}

方案3:换用集成测试注解

如果测试需要加载更多上下文组件,可以直接用集成测试注解替换,无需手动配置上下文:

@SpringBootTest
@AutoConfigureMockMvc
class TravelControllerTest {
  // 其余代码和你原有逻辑保持一致即可
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:24:02