1. 概述
本文将手把手带你用 MockMvc
实现对 Spring 中 Multipart POST 接口的测试。这类接口常见于文件上传场景,测试时需要模拟带文件的表单提交,稍有不慎就容易踩坑。掌握正确的姿势,能让你的单元测试简单粗暴又可靠。
2. Maven 依赖
测试前,确保你的 pom.xml
引入了必要的依赖。核心是 JUnit 和 Spring Test:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.16.RELEASE</version>
<scope>test</scope>
</dependency>
✅ 这两个依赖是基石,缺一不可。如果你用的是 Spring Boot,通常 spring-boot-starter-test
已经帮你打包好了。
3. 测试 Multipart POST 接口
3.1 接口定义
先看一个典型的文件上传接口:
@PostMapping(path = "/upload")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
return file.isEmpty() ?
new ResponseEntity<String>(HttpStatus.NOT_FOUND) : new ResponseEntity<String>(HttpStatus.OK);
}
这个接口干了两件事:
- 接收名为
file
的文件参数。 - 如果文件非空,返回 200 OK;否则返回 404 NOT FOUND。
3.2 编写测试
接下来是重头戏——如何用 MockMvc
模拟这个上传请求。
步骤一:注入上下文
测试类中,先自动注入 WebApplicationContext
,它是构建 MockMvc
的原材料:
@Autowired
private WebApplicationContext webApplicationContext;
步骤二:构造测试用例
@Test
public void whenFileUploaded_thenVerifyStatus()
throws Exception {
MockMultipartFile file
= new MockMultipartFile(
"file", // 参数名,必须和 @RequestParam 一致
"hello.txt", // 原始文件名
MediaType.TEXT_PLAIN_VALUE, // 内容类型
"Hello, World!".getBytes() // 文件内容
);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(multipart("/upload").file(file))
.andExpect(status().isOk());
}
关键点解析:
- ✅ **
MockMultipartFile
**:用来模拟一个上传的文件。构造函数的四个参数缺一不可,尤其是第一个参数file
,必须和接口的@RequestParam("file")
完全匹配。 - ✅ **
MockMvcBuilders.webAppContextSetup()
**:基于 Spring 容器上下文构建一个接近真实环境的测试MockMvc
。 - ✅ **
multipart("/upload").file(file)
**:这是精髓。multipart()
方法明确告诉MockMvc
这是一个 multipart 请求,并通过.file()
添加文件。 - ✅ **
.andExpect(status().isOk())
**:断言返回状态码为 200,验证业务逻辑正确。
⚠️ 踩坑提醒:
- 如果你用
post("/upload")
而不是multipart()
,请求体格式不对,测试会失败。 - 文件参数名(
"file"
)必须和接口定义严格一致,否则后端收不到文件,file.isEmpty()
会返回true
,导致断言失败。
4. 总结
本文通过一个简单例子,展示了如何使用 MockMvc
和 MockMultipartFile
对 Spring 的 Multipart POST 接口进行有效测试。
核心就三点:
- 用
MockMultipartFile
构造虚拟文件。 - 用
multipart()
而不是post()
发起请求。 - 确保参数名、路径完全匹配。
这套方法简单直接,能覆盖绝大多数文件上传测试场景。
完整代码示例已托管至 GitHub: https://github.com/yourname/spring-tutorials/tree/master/spring-mvc-java-2