Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MaxUploadSizeExceededException not thrown in tests

I have a simple spring app, with a controller that expects multipart file. For testing purpose I have set the MaxUploadSize size to just 50 bytes. When I deploy the war in tomcat I get the expected MaxUploadSizeExceededException for larger files, but if I use the same file in unit test then the test does not work.


Config

@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = {...})
public class MyApplication extends WebMvcConfigurerAdapter {

  @Bean
  public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver commonsMultipartResolver =
        new CommonsMultipartResolver();
    commonsMultipartResolver.setDefaultEncoding("utf-8");
    commonsMultipartResolver.setMaxUploadSize(50);
    return commonsMultipartResolver;
  }
}

@RestController
@RequestMapping("/metadata")
public class MyController {

  @RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public String metadata(@RequestParam MultipartFile file)  {
     //some processing...
  }
}

Test

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyApplication.class)
public class MyControllerTest {
...
@Test
  public void testDocx() throws Exception {
    byte[] docx = FileUtils.readFileToByteArray(new File(
            "src/test/resources/testdocs/test.docx"));
    MockMultipartFile multipartFile = new MockMultipartFile("file", "test.docx", "", docx);
    this.mvc.perform(fileUpload("/metadata").file(multipartFile))
        .andDo(print()).andExpect(status().is5xxServerError()); 
   //doesn't work, returns 200
  }
}

Spring version: 4.1.6

like image 799
sidgate Avatar asked Sep 07 '17 13:09

sidgate


1 Answers

I bumped into the same issue and fortunately I was able to solve it.

I assume this.mvc is a instance of MockMvc. Accordingly spring documentation:

Another useful approach is to not start the server at all but to test only the layer below that, where Spring handles the incoming HTTP request and hands it off to your controller. That way, almost of the full stack is used, and your code will be called in exactly the same way as if it were processing a real HTTP request but without the cost of starting the server. To do that, use Spring’s MockMvc and ask for that to be injected for you by using the @AutoConfigureMockMvc annotation on the test case.

Since there is no server started and this exception is thrown by Tomcat, it will never be thrown. I just had to remove it and use TestRestTemplate for calling the endpoint and worked like a charm. There is a fine example here.

like image 71
Eduardo Lima Avatar answered Sep 29 '22 18:09

Eduardo Lima