我正在尝试在spring mvc中编写一个控制器的单元测试,该控制器接受带有文件的mulitpart表单数据以及其他表单数据。我可以在测试时将请求发送到控制器,但无法访问文件或发送的数据。在控制器中收到的文件项似乎为空,在下面的代码中标记为“ fileItemsEmpty”。我能够点击api并从UI发送实际数据。非常感谢您的帮助。
ControllerCode:
@RequestMapping(value = "/upload-file", method = RequestMethod.POST, produces = CommonConstants.PRODUCES_JSON)
@ResponseBody
public String uploadFile(HttpServletRequest request, @NonNull Principal principal) throws Exception {
try {
String attribute1 = "";
String attribute2 = "";
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
fileItemsEmpty -> for (FileItem item : items) {
if(item.isFormField()) {
switch (item.getFieldName()) {
case "Attribute1":
attribute1 = item.getString("UTF-8");
break;
case "Attribute2":
attribute2 = item.getString("UTF-8");
break;
default:
log.info("Unknown Attribute received {}",
item.getFieldName());
}
} else {
BufferedReader br = new BufferedReader(new InputStreamReader(item.getInputStream(), StandardCharsets.UTF_8.name()));
String line = br.readLine();
while (line != null) {
//some computation from the file
}
br.close();
}
}
} catch (FileUploadException e) {
e.printStacktrace();
}
//Perform computation based on attribute1 and attribute2 and return string data.
}
单元测试:
@Test
public void testfileUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "file.txt", "", "file contents".getBytes());
MockMultipartFile attribute1 = new MockMultipartFile("Attribute1", "", "", "attribute1 value".getBytes());
MockMultipartFile attribute2 = new MockMultipartFile("Attribute2", "", "", "attribute2 value".getBytes());
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", "----WebKitFormBoundary");
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.fileUpload("/upload-file")
.file(file)
.file(attribute1)
.file(attribute2)
.contentType(mediaType)
.principal(principal))
.andExpect(status().isOk()).andReturn();
}
角度代码:
uploadFile(event) {
event.target.disabled = true;
var formData = new FormData();
formData.append('Attribute1', 'value1');
formData.append('Attribute2', value2);
formData.append('file', $('#fileInput')[0].files[0]);
this.http.post<any>("/upload-file", formData);
}
答案 0 :(得分:0)
您正在使用以下方法覆盖您的实际文件:
.file(file)
.file(attribute1)
.file(attribute2)
attribute1
和attribute2
都是附加的表单数据,而不是文件。您不应该使用MockMultipartFile
来创建它们,而只能使用实际文件(语音图像,pdf,docx)来创建它们。
您可以使用MockMvc
:.param()
的另一种方法来设置其他表单数据。
因此,请尝试以下操作:
MvcResult mvcResult = mockMvc
.perform(MockMvcRequestBuilders.fileUpload("/upload-file")
.file(file)
.param("Attribute1", "attribute1")
.param("Attribute2", "attribute2")
.contentType(mediaType)
.principal(principal))
.andExpect(status().isOk()).andReturn();
PS:.fileUpload()
已过时(至少在Spring Test 5.2.6中已弃用),您应该改为使用.multipart()
。