使用 Spring 使用 multipartfile 测试 POST 请求

问题描述

我有一个控制器发送 post 请求,它运行良好并与客户端正确通信。但是,我无法在 JUnit 中对其进行测试。 控制器接收一个 multipartfile 以及 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","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'

解决方法

以防它对其他人有帮助,我通过添加一个真正的 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());
}