Using Spring MVC Test to Unit Test a Multipage POST Request

I have the following request handler to save a car. I checked that this works when I use, for example, curl. Now I want a unit test method with Spring MVC Test. I tried using fileUploader, but I am unable to get it to work. I also can not add the JSON part.

How could I unit test use this method using Spring MVC Test? I can not find any examples.

@RequestMapping(value = "autos", method = RequestMethod.POST) public ResponseEntity saveAuto(@RequestPart(value = "data") AutoResource, @RequestParam(value = "files[]", required = false) List<MultipartFile> files) {...} 

I want to add a JSON representation for my auto + one or more files.

I will add 100 points for the correct answer!

+95
java spring java-ee spring-mvc unit-testing
Feb 15 '14 at 16:58
source share
4 answers

Since MockMvcRequestBuilders#fileUpload deprecated, you can use MockMvcRequestBuilders#multipart(String, Object...) which returns MockMultipartHttpServletRequestBuilder . Then file(MockMultipartFile) calls file(MockMultipartFile) .

Here is a working example. Given @Controller

 @Controller public class NewController { @RequestMapping(value = "/upload", method = RequestMethod.POST) @ResponseBody public String saveAuto( @RequestPart(value = "json") JsonPojo pojo, @RequestParam(value = "some-random") String random, @RequestParam(value = "data", required = false) List<MultipartFile> files) { System.out.println(random); System.out.println(pojo.getJson()); for (MultipartFile file : files) { System.out.println(file.getOriginalFilename()); } return "success"; } static class JsonPojo { private String json; public String getJson() { return json; } public void setJson(String json) { this.json = json; } } } 

and unit test

 @WebAppConfiguration @ContextConfiguration(classes = WebConfig.class) @RunWith(SpringJUnit4ClassRunner.class) public class Example { @Autowired private WebApplicationContext webApplicationContext; @Test public void test() throws Exception { MockMultipartFile firstFile = new MockMultipartFile("data", "filename.txt", "text/plain", "some xml".getBytes()); MockMultipartFile secondFile = new MockMultipartFile("data", "other-file-name.data", "text/plain", "some other type".getBytes()); MockMultipartFile jsonFile = new MockMultipartFile("json", "", "application/json", "{\"json\": \"someValue\"}".getBytes()); MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); mockMvc.perform(MockMvcRequestBuilders.multipart("/upload") .file(firstFile) .file(secondFile) .file(jsonFile) .param("some-random", "4")) .andExpect(status().is(200)) .andExpect(content().string("success")); } } 

And the @Configuration class

 @Configuration @ComponentScan({ "test.controllers" }) @EnableWebMvc public class WebConfig extends WebMvcConfigurationSupport { @Bean public MultipartResolver multipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); return multipartResolver; } } 

The test should pass and give you a conclusion

 4 // from param someValue // from json file filename.txt // from first file other-file-name.data // from second file 

It should be noted that you send JSON in the same way as any other multicomponent file, except for another type of content.

+223
Feb 15 '14 at 23:36
source share

Look at this example, taken from the spring MVC showcase, this is a link to the source code :

 @RunWith(SpringJUnit4ClassRunner.class) public class FileUploadControllerTests extends AbstractContextControllerTests { @Test public void readString() throws Exception { MockMultipartFile file = new MockMultipartFile("file", "orig", null, "bar".getBytes()); webAppContextSetup(this.wac).build() .perform(fileUpload("/fileupload").file(file)) .andExpect(model().attribute("message", "File 'orig' uploaded successfully")); } } 
+16
Feb 15 '14 at 17:30
source share

The MockMvcRequestBuilders.fileUpload method MockMvcRequestBuilders.fileUpload not recommended to use MockMvcRequestBuilders.multipart instead.

That's an example:

 import static org.hamcrest.CoreMatchers.containsString; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.multipart.MultipartFile; /** * Unit test New Controller. * */ @RunWith(SpringRunner.class) @WebMvcTest(NewController.class) public class NewControllerTest { private MockMvc mockMvc; @Autowired WebApplicationContext wContext; @MockBean private NewController newController; @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(wContext) .alwaysDo(MockMvcResultHandlers.print()) .build(); } @Test public void test() throws Exception { // Mock Request MockMultipartFile jsonFile = new MockMultipartFile("test.json", "", "application/json", "{\"key1\": \"value1\"}".getBytes()); // Mock Response NewControllerResponseDto response = new NewControllerDto(); Mockito.when(newController.postV1(Mockito.any(Integer.class), Mockito.any(MultipartFile.class))).thenReturn(response); mockMvc.perform(MockMvcRequestBuilders.multipart("/fileUpload") .file("file", jsonFile.getBytes()) .characterEncoding("UTF-8")) .andExpect(status().isOk()); } } 
+12
May 21 '18 at 18:42
source share

If you use Spring4 / SpringBoot 1.x, then it is worth mentioning that you can also add "text" (json) parts. This can be done using the MockMvcRequestBuilders.fileUpload () file. (MockMultipartFile) (which is required because the .multipart() method is not available in this version):

 @Test public void test() throws Exception { mockMvc.perform( MockMvcRequestBuilders.fileUpload("/files") // file-part .file(makeMultipartFile( "file-part" "some/path/to/file.bin", "application/octet-stream")) // text part .file(makeMultipartTextPart("json-part", "{ \"foo\" : \"bar\" }", "application/json")) .andExpect(status().isOk()))); } private MockMultipartFile(String requestPartName, String filename, String contentType, String pathOnClassPath) { return new MockMultipartFile(requestPartName, filename, contentType, readResourceFile(pathOnClasspath); } // make text-part using MockMultipartFile private MockMultipartFile makeMultipartTextPart(String requestPartName, String value, String contentType) throws Exception { return new MockMultipartFile(requestPartName, "", contentType, value.getBytes(Charset.forName("UTF-8"))); } private byte[] readResourceFile(String pathOnClassPath) throws Exception { return Files.readAllBytes(Paths.get(Thread.currentThread().getContextClassLoader() .getResource(pathOnClassPath).toUri())); } } 
+1
Jan 24 '19 at 18:26
source share



All Articles