5

My code was initially breaking if I try and push a large file (anything above 1MB size). It is working fine now and able to accommodate the file sizes I want by adding the following in the properties file.

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

But how can I write a proper unit/integration test on this to ensure it allows file size up to 10MB?

The following has a good test example (the accepted answer) but it is using a mock file setup to test. Using Spring MVC Test to unit test multipart POST request

  1. Is there a way I could mock and specify file size?
  2. Or actually pass in a real large file for testing (preferably not)?
  3. Or a better way to do this, test I can accept a large file up to 10MB?

This is the method to be tested

@PostMapping(path = "/example", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<SomeResponse> upload(@PathVariable(@RequestPart("file") MultipartFile file) {

    //we won't even get inside thi method and would fail if the file size is over 1MB previously. 

    // It works currently when I add files with size above 1MB 
    // cos I added the above 2 lines (spring.servlet.... in the properties file)

    // some logic which works fine.

    SomeResponse obj = // 
    return new ResponseEntity<>(obj, HttpStatus.OK);
}

This is current test (and there are other tests to test negative scenarios)

@Test
public void testValidUpload() throws Exception {
    String fileContents = "12345";
    String expectedFileContents = "12345\nSomeData";

    mockServer.expect(requestTo("http://localhost:8080/example"))
        .andExpect(method(HttpMethod.POST))
        .andExpect(expectFile("file", "test.csv", expectedFileContents))
        .andRespond(withStatus(HttpStatus.OK)
                .contentType(MediaType.TEXT_PLAIN)
                .body("done")
        );

    String response = this.mvc.perform(multipart("/example")
        .file(new MockMultipartFile("file", "filename.csv", MediaType.TEXT_PLAIN_VALUE, fileContents.getBytes())))
        .andExpect(status().isOk())
        .andExpect(content().contentType(APPLICATION_JSON))
        .andExpect(jsonPath("responseStatusCode", Matchers.equalTo("200")))
        .andExpect(jsonPath("httpStatus", Matchers.equalTo("OK")))
        .andReturn().getResponse().getContentAsString();

    Response response = objectMapper.readValue(response, Response.class);
    assertEquals(HttpStatus.OK, response.getHttpStatus());
    assertEquals(5, response.id());
}
karvai
  • 2,417
  • 16
  • 31
  • HTTP allows to check whether a server is able to handle large files before actually sending that large payload to the server. Here the upfront request contains an [Expect](https://datatracker.ietf.org/doc/html/rfc7231#section-5.1.1) header paired with the `Content-Type` and `Content-Length` header, that as [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2) states is just an indication for the anticipated size of a resource. This should be rather straight-forward to test – Roman Vottner Oct 30 '21 at 09:59

1 Answers1

0

You can try something like this:

byte[] bytes = new byte[1024 * 1024 * 10];
MockMultipartFile firstFile = new MockMultipartFile("data", "file1.txt", "text/plain", bytes);

See documentation.

You can also refer to this article.