我正在为接受MultipartFile
的控制器方法编写单元测试
和自定义对象MessageAttachment
。到目前为止,我可以看到MultipartFile是请求的正确格式,但MessageAttachment不是。
messageAttachment
的解析引发了MethodArgumentConversionNotSupportedException
的服务器端500错误。
在测试中将MessageAttachment转换为MockMultipartFile似乎是一个问题。这类似于此处显示的示例-https://stackoverflow.com/a/21805186
问题:
如何使用MockMvc解决MethodArgumentConversionNotSupportedException?
正在测试的控制器方法
@RequestMapping(value = "/", method = RequestMethod.POST, consumes = "multipart/form-data", produces = "application/json")
public ResponseEntity<MessageAttachment> handleFileUpload(@RequestParam(value = "file", required = true) MultipartFile file, @RequestParam(value = "messageAttachment") MessageAttachment messageAttachment) {
//do stuff with the file and attachment passed in..
MessageAttachment attachment = new MessageAttachment();
return ResponseEntity.accepted().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getOriginalFilename() + "\"").body(attachment);
}
MockMvc测试
@Test
public void shouldSaveUploadedFile() throws Exception {
// Given
ObjectMapper mapper = new ObjectMapper();
MessageAttachment messageAttachment = new MessageAttachment();
messageAttachment.setTimestamp(new Date());
MockMultipartFile multipartFile = new MockMultipartFile("file", "test.txt", "text/plain",
"Spring Framework".getBytes());
//Mapping the msgAttachment to a MockMultipartFile HERE
MockMultipartFile msgAttachment = new MockMultipartFile("messageAttachment", "","application/json",
mapper.writeValueAsString(messageAttachment).getBytes());
// When
this.mockMvc.perform(MockMvcRequestBuilders.multipart("/media/")
.file(multipartFile)
.file(msgAttachment)).andDo(MockMvcResultHandlers.print());
}
MockMvcResultHandlers.print()的控制台输出
MockHttpServletRequest:
HTTP Method = POST
Request URI = /media/
Parameters = {}
Headers = {Content-Type=[multipart/form-data]}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = com.fizz.buzz.fizzapi.controller.MediaUploadController
Method = public org.springframework.http.ResponseEntity<com.fizz.buzz.fizzapi.model.MessageAttachment> com.fizz.buzz.fizzapi.controller.MediaUploadController.handleFileUpload(org.springframework.web.multipart.Mu
ltipartFile,com.fizz.buzz.fizzapi.model.MessageAttachment,javax.servlet.http.HttpServletRequest)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
答案 0 :(得分:-1)
对于部分@RequestPart
,您需要使用@RequestParam
而不是application/json
。 @RequestPart
状态的Javadoc
受支持的方法参数类型包括
MultipartFile
借助Spring的MultipartResolver
抽象,javax.servlet.http.Part
结合Servlet 3.0多部分 请求或其他任何方法参数的内容 该部分通过HttpMessageConverter
传递给 请考虑请求部分的“ Content-Type”标头。这是 类似于@RequestBody
为解决基于 非分段常规请求的内容。请注意,
@RequestParam
批注也可以用于关联 带有方法参数的“ multipart / form-data”请求的一部分 支持相同的方法参数类型。 主要区别在于 当方法参数不是字符串时,@RequestParam
依赖于类型 通过注册的Converter
或PropertyEditor
进行转换@RequestPart
依靠HttpMessageConverters
的考虑 请求部分的“内容类型”标头。@RequestParam
与@RequestPart
一起用于名称-值表单字段 可以与包含更复杂内容(例如JSON,XML)的部分一起使用。
大概您没有注册Converter
或PropertyEditor
来解析该部分的内容,而JSON的HttpMessageConverter
会自动注册(取决于您的Spring) MVC /引导版本)(如果您在类路径中有Jackson)。