Search code examples
production-environmentspring-testspring-data-restxml-configurationtest-environments

Use CommonsMultipartResolver in Spring and config in test


I have an integration test that make a request (uploading a file) on my controller. The test works without setup any CommonsMultipartResolver. But in the moment where I have to setup the production environment I have to add the CommonsMultipartResolver. But this has the side effect that my test don't work. It sames that the xml configuration is needed for Production, and not for test. I know that there are the possibility to define profiles for test and production environment. Is there any other possibility to not have a profile?

The configuration of the multipartresolver is simple:

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
    p:maxUploadSize="1000000000">
</bean>

and my test is also simple:

MockMultipartFile aFileObject = new MockMultipartFile("file", "filename.txt", "text/plain", "a File message".getBytes());
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", "xyz");
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
MockHttpServletRequestBuilder action = fileUpload(path).file(aFileObject));

mockMvc=MockMvcBuilders.webAppContextSetup(webApplicationContext)
     .addFilter(new DelegatingFilterProxy("springSecurityFilterChain", webApplicationContext), "/*")
     .build()

ResultActions resultPost =mockMvc.perform(action.contentType(mediaType));
assertThat(.....

(I have simplified a little bit the test code (this is not the issue here. It works.) )

Has anyone an idea how I can figure out the configuration of the Multipartresolver when the test are running, and enabling when I put all in production without that I have to remember every time to comment the config?


Solution

  • MockMvc does not run with a Servlet container. It uses the MockHttpServletRequest/Response which means you set up the request manually. That includes file uploads. Essentially by building the request with fileUpload(..).file(..) you're manually setting up a MockMultipartHttpServletRequest (same thing the MultipartResolver would do at runtime in an actual Servlet container). So when the DispatcherServlet processes this request, it realizes the request has already been parsed as a multipart request, and is happy to move on without having to call the MultipartResolver.

    Bottom line, if you want to test what your controller does with a multipart request, it should work fine (see example test: https://github.com/spring-projects/spring-framework/blob/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FileUploadControllerTests.java). If you want to test an actual upload with MultipartResolver getting involved, you'll need to write an integration test with an in-memory server. Chances are the former is what you need for most cases and then one test with a real server to ensure your resolver is in the configuration should be okay.