MockMultipartFile 是 Spring Test 提供的模拟 MultipartFile 的测试类,用于绕过 IO 在 Controller 层测试文件上传;需显式指定 UTF-8 编码、正确 contentType(如 "application/xml;charset=UTF-8")及 .xml 后缀文件名,并用 fileUpload() 而非 post() 发送请求。

MockMultipartFile 是什么,为什么不能直接 new
MockMultipartFile 是 Spring Test 模块提供的一个测试用类,专为模拟 org.springframework.web.multipart.MultipartFile 设计。它不是真实文件上传的替代品,而是绕过文件系统 IO、让 Controller 层能正常接收并解析 multipart 请求的“假文件”。直接 new MultipartFile 接口会报错,因为它是接口,且 Spring 的文件解析逻辑强依赖具体实现的 getInputStream()、getOriginalFilename() 等行为。
构造 MockMultipartFile 上传 XML 文件的正确姿势
关键点在于:内容字节数组必须是合法 XML 字符串编码后的结果,且 contentType 要匹配(比如 application/xml 或 text/xml),否则某些 XML 解析器(如 @RequestBody @XmlRootElement)可能拒绝处理。
- 文件名必须带
.xml后缀,否则部分基于后缀路由的拦截器或日志可能出问题 -
bytes参数要用String.getBytes(StandardCharsets.UTF_8)显式指定编码,避免平台默认编码不一致导致解析失败 -
contentType推荐写成"application/xml;charset=UTF-8",和实际生产请求头对齐
String xmlContent = ""; byte[] xmlBytes = xmlContent.getBytes(StandardCharsets.UTF_8); MockMultipartFile file = new MockMultipartFile( "file", // 表单字段名,要和 @RequestParam("file") 一致 "test.xml", // 原始文件名,必须含 .xml "application/xml;charset=UTF-8", // content-type xmlBytes // 字节内容 ); 123 Alice
在 MockMvc 测试中发送 XML 文件请求
注意:不能用 contentType(MediaType.MULTIPART_FORM_DATA) 简单设置,必须用 fileUpload() 方法触发 multipart 处理链;否则 Spring 不会调用 MultipartResolver,Controller 收到的仍是 null。
-
fileUpload("/api/upload")是入口,不是post().content(...) - 如果接口还带其他表单字段(如
userId),用.param("userId", "456")追加 - 若 Controller 使用
@RequestPart接收 XML,确保字段名与MockMultipartFile构造时第一个参数一致
mockMvc.perform(fileUpload("/api/upload")
.file(file) // 必须调用 .file()
.param("userId", "456") // 其他表单参数
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200));
常见报错及对应修复点
XML 上传测试失败,大概率不是逻辑错,而是 MockMultipartFile 构造或请求方式不对:
-
Required request part 'file' is not present→ 检查fileUpload()是否用了,以及MockMultipartFile第一个参数(字段名)是否和 Controller 的@RequestParam或@RequestPart值一致 -
Content type 'application/octet-stream' not supported→MockMultipartFile的contentType参数没设对,或设成了空字符串 - XML 解析异常(如
org.xml.sax.SAXParseException: Content is not allowed in prolog)→ 字节数组含 BOM 或编码不一致,改用StandardCharsets.UTF_8显式编码 - 测试通过但线上失败 → 检查生产环境 Nginx/Apache 是否限制了
client_max_body_size或去除了Content-Type头










