【问题标题】:Test POST request with multipartfile with Spring使用 Spring 使用 multipartfile 测试 POST 请求
【发布时间】:2021-02-08 14:45:39
【问题描述】:

我有一个发送帖子请求的控制器,它运行良好并与客户端正确通信。但是,我无法在 JUnit 中对其进行测试。 控制器接收一个多部分文件,以及 2 个布尔参数(这是必需的),并且只接受“application/xls”作为内容类型。 为了进行测试,我正在模拟 multipartfile 和参数。但是,当我这样做时,我收到以下错误:handler.RestExceptionHandler: Exception caught. Wrong file type;\n Import .xls or .xlsx file(来自我的异常处理程序)。

    @PostMapping(value = "/file",
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
            produces = MediaType.TEXT_HTML_VALUE)
    public ResponseEntity<InputStreamResource> parseMultipartFile(
            @RequestParam MultipartFile multipartFile,
            @RequestParam boolean hasOnlyOneSheet,
            @RequestParam boolean hasBorders) throws IOException {

        String fileContentType = multipartFile.getContentType();
        if (mimeType.contains(fileContentType)) {

            InputStream parsedFile = multipartFileToHtmlService.multipartFileToHtml(multipartFile, hasOnlyOneSheet, hasBorders);
            InputStreamResource inputStreamResource = new InputStreamResource(parsedFile);

            return ResponseEntity.ok(inputStreamResource);
        } else {
            throw new UnsupportedImportMediaTypeException("Wrong file type;\n Import .xls or .xlsx file");
        }
    }

这是我的测试:

@WebMvcTest
@RunWith(SpringRunner.class)
class HtmlExporterControllerTest {

    @MockBean
    MultipartFileToHtmlService multipartFileToHtmlService;

    @MockBean
    HtmlToHtmlServiceFactory htmlToHtmlServiceFactory;

    @Autowired
    MockMvc mockMvc;

    @Test
   public void parseMultipartFile_Should_Return_Ok() throws Exception {
        MockMultipartFile mockMultipartFile = new MockMultipartFile(
                "multipartFile",
                "test.xls",
                "application/x-xls",
                "Hello World!".getBytes());

        mockMvc.perform(MockMvcRequestBuilders.multipart("/file")
                .file("multipartFile", mockMultipartFile.getBytes())
                .param("hasOnlyOneSheet", "true")
                .param("hasBorders", "true"))
                .andExpect(status().isOk());
    }

为避免此问题,我尝试将布尔值作为新的 multipart/form-data 传递,如下所示:

    @Test
   public void parseMultipartFile_Should_Return_Ok() throws Exception {
        MockMultipartFile mockMultipartFile = new MockMultipartFile(
                "multipartFile",
                "test.xls",
                "application/x-xls",
                "Hello World!".getBytes());

        MockMultipartFile mockMultipartFile1 = new MockMultipartFile(
                "hasBorders",
                "",
                "",
                "true".getBytes());

        MockMultipartFile mockMultipartFile2 = new MockMultipartFile(
                "hasOnlyOneSheet",
                "",
                "",
                "true".getBytes());

        mockMvc.perform(MockMvcRequestBuilders.multipart("/file")
                .file("multipartFile", mockMultipartFile.getBytes())
                .file("hasOnlyOneSheet", mockMultipartFile1.getBytes())
                .file("hasBorders", mockMultipartFile2.getBytes()))
                .andExpect(status().isOk());
    }

然后,我收到以下错误Failed to convert value of type 'org.springframework.mock.web.MockMultipartFile' to required type 'boolean';

再一次,请求有效,我也可以在Postman 上完成,这里是 curl 请求:

curl --location --request POST 'http://localhost:8080/file' \
--form 'multipartFile=@/MyPath/test.xlsx' \
--form 'hasBorders=true' \
--form 'hasOnlyOneSheet=true'

【问题讨论】:

  • 异常的堆栈跟踪会有所帮助。顺便说一句,将布尔值作为 MultipartFile 传递是没有意义的。
  • 异常是错误的文件类型异常,应该只是“application/xls”类型(但在我的测试用例中应该是这种情况)。如果我完全删除异常处理程序,我会得到`请求处理失败;嵌套异常是 java.lang.IllegalArgumentException: InputStream must not be null`
  • 您能否使用完整的堆栈跟踪更新问题以进行初始测试?另外,提供一个示例 test.xlsx 文件。

标签: java spring testing controller multipartfile


【解决方案1】:

如果它对其他人有帮助,我通过添加一个真正的 excel 表来解决它:

@WebMvcTest
@RunWith(SpringRunner.class)
class HtmlExporterControllerTest {

@MockBean
MultipartFileToHtmlService multipartFileToHtmlService;

@MockBean
HtmlToHtmlServiceFactory htmlToHtmlServiceFactory;

@Autowired
MockMvc mockMvc;

@Test
public void parseMultipartFile_Should_Return_Ok() throws Exception {
    MockMultipartFile mockMultipartFile = new MockMultipartFile(
            "multipartFile",
            "test.xls",
            "application/x-xls",
            new ClassPathResource("test.xls").getInputStream());

    mockMvc.perform(MockMvcRequestBuilders.multipart("/file")
            .file(mockMultipartFile)
            .param("hasOnlyOneSheet", "true")
            .param("hasBorders", "true"))
            .andExpect(status().isOk());
}

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    相关资源
    最近更新 更多