Spring Boot 单元测试中 MockMvc 为空的解决方案
发布时间 - 2026-01-02 00:00:00 点击率:次本文详解 spring boot 中 `@webmvctest` 下 `mockmvc` 注入失败(为 null)的根本原因,包括注解冲突、版本不兼容及配置冗余问题,并提供规范、可运行的 web 层测试最佳实践。
在 Spring Boot 测试中,MockMvc 是验证控制器(Controller)行为的核心工具。但如你所遇——MockMvc 字段始终为 null,即使添加了 @Autowired 和各类测试注解(如 @SpringBootTest、@WebMvcTest、@AutoConfigureMockMvc),往往源于注解混用冲突与依赖版本错配两大关键问题。
✅ 正确做法:单一职责 + 精准注解
@WebMvcTest 本身已自动启用 MockMvc 的自动配置,无需额外添加 @AutoConfigureMockMvc(它在此场景下冗余且可能干扰上下文加载),更严禁与 @SpringBootTest 同时使用——二者目标冲突:
- @WebMvcTest:仅加载 Web 层(Controller + 配置),轻量、快速,适合 MVC 接口测试;
- @SpringBootTest:加载完整应用上下文,重量级,适用于集成测试,会覆盖 @WebMvcTest 的隔离性,导致 MockMvc 注入失效。
✅ 正确测试类应精简如下:
@WebMvcTest(BookController.class) // 仅扫描 BookController 及其 Web 相关 Bean class BookControllerTest { @Autowired private MockMvc mockMvc; @MockBean // 自动 mock 依赖的 Service,避免真实调用 private BookService bookService; @Test void testListBooks() throws Exception { // 模拟 service 返回值 when(bookService.listBooks()).thenReturn(List.of(new Book("Spring Boot in Action"))); mockMvc.perform(get("/api/books/list")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)); } }
⚠️ 关键修复点说明
移除冲突注解:
删除 @SpringBootTest 和 @AutoConfigureMockMvc —— @WebMvcTest 已隐式包含所需配置。补充 @MockBean:
Controller 通常依赖 Service,必须用 @MockBean 替代真实 Bean,否则 @WebMvcTest 会因找不到 BookService Bean 而启动失败或注入异常。-
修正 Maven 依赖版本一致性:
你的 pom.xml 存在严重版本冲突:- 父 POM 为 Spring Boot 2.1.0.RELEASE,但 spring-boot-starter-web 显式指定为 3.0.0(属 Spring Boot 3.x,基于 Jakarta EE 9+,与 Spring Boot 2.x 不兼容);
- JUnit 5 版本(5.2.0)过旧,且 mockito-junit-jupiter 4.6.1 与 Spring Boot 2.1 不匹配。
✅ 推荐统一使用 Spring Boot 2.7.x(LTS)或 3.2+(最新 LTS),并删除所有显式
,交由父 POM 管理: org.springframework.boot spring-boot-starter-webSpring Boot 2.7.x 默认使用 JUnit Jupiter 5.8+ 和 Mockito 4.11+,完全兼容 @ExtendWith(MockitoExtension.class)(但 @WebMvcTest 已内置 Mockito 支持,@ExtendWith 亦可省略)。
-
Controller 方法可见性修正:
你代码中 listBooks() 声明为 private,但 Spring MVC 要求 Handler 方法必须是 public:@GetMapping("/list") public ResponseEntity
? 总结:三步排错清单
| 问题类型 | 错误表现 | 解决方案 |
|---|---|---|
| 注解冲突 | MockMvc 为 null,测试启动慢或报 NoSuchBeanDefinitionException | ✅ 仅保留 @WebMvcTest(YourController.class),删除 @SpringBootTest、@AutoConfigureMockMvc |
| 依赖未 Mock | MockMvc 不为 null 但请求抛 NullPointerException(service 未初始化) | ✅ 添加 @MockBean YourService service 并设置 when(...).thenReturn(...) |
| 版本不一致 | 编译通过但运行时报 ClassNotFoundException 或 IncompatibleClassChangeError | ✅ 删除所有显式 |
遵循以上规范,MockMvc 将被正确注入,测试可稳定执行——这是 Spring Boot Web 层单元测试的基石实践。
# js
# json
# app
# 工具
# springboot
# spring mvc
# red
# mvc
# spring
# spring boot
# maven
# junit
# NULL
# xml
# 接口
# class
# public
# private
# 加载
# 移除
# 不兼容
# 这是
# 在此
# 找不到
# 适用于
# 所需
# 两大
# 将被
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
Angular 表单中正确绑定输入值以确保提交与验证正常工作
浅述节点的创建及常见功能的实现
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
Laravel如何实现文件上传和存储?(本地与S3配置)
用v-html解决Vue.js渲染中html标签不被解析的问题
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
googleplay官方入口在哪里_Google Play官方商店快速入口指南
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
EditPlus中的正则表达式实战(5)
高端智能建站公司优选:品牌定制与SEO优化一站式服务
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
如何快速搭建个人网站并优化SEO?
UC浏览器如何设置启动页 UC浏览器启动页设置方法
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】
中山网站推广排名,中山信息港登录入口?
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
Laravel如何使用Livewire构建动态组件?(入门代码)
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
JS实现鼠标移上去显示图片或微信二维码
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
网站制作软件免费下载安装,有哪些免费下载的软件网站?
linux写shell需要注意的问题(必看)
Python企业级消息系统教程_KafkaRabbitMQ高并发应用
南京网站制作费用,南京远驱官方网站?
如何在Windows服务器上快速搭建网站?
Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势
怎样使用JSON进行数据交换_它有什么限制
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
详解jQuery中基本的动画方法
Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理
Java遍历集合的三种方式
如何用花生壳三步快速搭建专属网站?
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
如何挑选最适合建站的高性能VPS主机?
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】
高端网站建设与定制开发一站式解决方案 中企动力
Laravel中的withCount方法怎么高效统计关联模型数量
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】


class) // 仅扫描 BookController 及其 Web 相关 Bean
class BookControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean // 自动 mock 依赖的 Service,避免真实调用
private BookService bookService;
@Test
void testListBooks() throws Exception {
// 模拟 service 返回值
when(bookService.listBooks()).thenReturn(List.of(new Book("Spring Boot in Action")));
mockMvc.perform(get("/api/books/list"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
}