@WebMvcTest 是 Spring Boot 5.1 中精准测试 Controller 层的核心方案,仅加载 Web MVC 基础设施与指定控制器,自动 Mock 服务依赖;需使用 spring-boot-starter-test 3.1.x+,通过 @MockBean 模拟 Service 并用 MockMvc 验证 HTTP 行为与 JSON 响应。

要在 Spring Boot 5.1 中对 Controller 层做精准、轻量、可隔离的测试,必须避开加载整个应用上下文,只让 Web MVC 基础设施和目标控制器生效,同时自动 Mock 服务层依赖——这正是 @WebMvcTest 的核心价值所在。
确认测试依赖已就位
打开 pom.xml,检查是否已声明 spring-boot-starter-test 且版本与 Spring Boot 5.1 兼容:【必须使用 3.1.x 或更高版本的 spring-boot-starter-test,低版本不支持 Spring Boot 5.1 的 Jakarta EE 9+ 命名空间】。若使用 Gradle,则对应依赖应为 testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.0' 及以上。
该依赖已内含 JUnit Jupiter、Mockito、AssertJ、JsonPath 和 spring-test,无需额外引入 spring-mock 或 mockito-core 单独版本。
编写最简 @WebMvcTest 类
在 src/test/java 下新建测试类,例如 UserControllerWebTest.java:
用 @WebMvcTest(UserController.class) 明确指定仅加载该控制器;不加参数则默认扫描所有 @Controller 和 @RestController。
@Autowired MockMvc mockMvc 是必需的——Spring Boot 测试框架会自动配置并注入它,无需手动构建。
不要在该测试类中添加 @SpringBootTest 或 @ContextConfiguration,否则将破坏切片机制,触发全量上下文加载。
验证 HTTP 路由与状态码
方法一:基础 GET 请求校验
调用 mockMvc.perform(get("/api/users/123")) → 接着链式调用 .andExpect(status().isOk()) → 再接 .andExpect(content().contentType(MediaType.APPLICATION_JSON))。
将 Spring Boot 2.7 项目升级到 Spring Boot 3.5 的实战流程,覆盖版本基线、依赖坐标替换、Jakarta 迁移、配置兼容、异步上下文传递改造与验证门禁。用于企业多模块 Maven 项目升级与排障。
方法二:带路径变量和请求头的 POST
写法:mockMvc.perform(post("/api/users").contentType(APPLICATION_JSON).header("X-Trace-ID", "abc123").content("{\"name\":\"Alice\",\"email\":\"a@b.com\"}")) → 断言 status().isCreated()。
注意:若控制器方法参数含 @Valid,但测试未提供合法 JSON,会直接返回 400,此时需先补全字段或显式断言 status().isBadRequest()。
模拟 Service 层行为(关键步骤)
第一步:在测试类字段上声明 @MockBean UserService userService。
第二步:在 @BeforeEach 方法中用 when(userService.findById(123L)).thenReturn(new UserDto(123L, "Bob")) 预设响应。
第三步:执行 mockMvc.perform(get("/api/users/123")) → 此时控制器内部调用的 userService.findById() 将返回你 stub 的对象,而非真实实现。
【@MockBean 必须作用于测试类级别,不能用 @Mock 替代;否则依赖不会被注入到 Controller 实例中】
第四步:用 .andExpect(jsonPath("$.name").value("Bob")) 验证响应体 JSON 字段值。

















