简体   繁体   中英

Test POST request with multipartfile with Spring

I have a controller sending post requests which is working well and communicating with the client correctly. However, I am unable to test it with in JUnit. The controller receives a multipartfile, along with 2 boolean parameters (that are required), and accept only "application/xls" as content type. To do the test I am mocking the multipartfile and the parameters. However, when I do it this way, I get the following error: handler.RestExceptionHandler: Exception caught. Wrong file type;\n Import.xls or.xlsx file handler.RestExceptionHandler: Exception caught. Wrong file type;\n Import.xls or.xlsx file (from my exception handler).

    @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");
        }
    }

and here is my test:

@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());
    }

To avoid this issue, I tried to pass the boolean values as new multipart/form-data like so:

    @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());
    }

But then, I get the following error Failed to convert value of type 'org.springframework.mock.web.MockMultipartFile' to required type 'boolean';

Once again, the request is working, i can also do it on Postman , here is the curl request:

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

In case it helps someone else, I solved it by adding a real excel sheet:

@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());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM