3

I have a requestMapping of the form:

@RequestMapping(
    value = "/submitCase",
    consumes =  MediaType.MULTIPART_FORM_DATA_VALUE,
    produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
    method = RequestMethod.POST
)
public Object submitCase(
    @RequestPart(name = "attachment[0]", required = false) MultipartFile attachment1,
    @RequestPart(name = "attachment[1]", required = false) MultipartFile attachment2,
    @RequestPart(name = "attachment[2]", required = false) MultipartFile attachment3,
    @RequestPart(name = "attachment[3]", required = false) MultipartFile attachment4,
    @RequestPart(name = "attachment[4]", required = false) MultipartFile attachment5,
    @RequestPart(name = "caseDetails") CaseDetails caseDetails) {}

Now I want to write a test for this with MockMvcBuilders. However I am unable to do so.

The challenge here is that the request handler consumes multipart/form-data, which consists of 4 Multipart Files, and 1 Json data.

Any ideas on how to solve this? Please bear in mind i am constrained to use Spring 4.3.

Please let me know if you require any more information.

user3762085
  • 31
  • 1
  • 3

1 Answers1

5

Have a look at the great example here: https://stackoverflow.com/a/21805186/3976662

Note, that MockMvcRequestBuilders.html#multipart used in the example is not available in Spring 4.3.0, yet. Use MockMvcRequestBuilders.html#fileUpload instead (deprecated in Spring 5).

CaseDetails.java:

public class CaseDetails {
    private String exampleAttr;

    public String getExampleAttr() {
        return exampleAttr;
    }

    public void setExampleAttr(String exampleAttr) {
        this.exampleAttr = exampleAttr;
    }
}

UploadController.java:

@Controller
public class UploadController {

    @RequestMapping(
            value = "/submitCase",
            consumes =  MediaType.MULTIPART_FORM_DATA_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
            method = RequestMethod.POST
    )
    @ResponseBody
    public Object submitCase(
            @RequestPart(name = "attachment[0]", required = false) MultipartFile attachment1,
            @RequestPart(name = "attachment[1]", required = false) MultipartFile attachment2,
            @RequestPart(name = "attachment[2]", required = false) MultipartFile attachment3,
            @RequestPart(name = "attachment[3]", required = false) MultipartFile attachment4,
            @RequestPart(name = "attachment[4]", required = false) MultipartFile attachment5,
            @RequestPart(name = "caseDetails") CaseDetails caseDetails) {

        Map<String,String> result = new HashMap<>();
        result.put("success", "true");

        return result;
    }
}

UploadControllerTest.java:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = UploadControllerTest.TestConfig.class)
public class UploadControllerTest {

    @Autowired
    private UploadController uploadController;

    @Test
    public void testSubmitCase() throws Exception {
        MockMultipartFile file1 = new MockMultipartFile("attachment[0]", "filename-1.txt", "text/plain", "1".getBytes());
        MockMultipartFile file2 = new MockMultipartFile("attachment[1]", "filename-2.txt", "text/plain", "2".getBytes());
        MockMultipartFile file3 = new MockMultipartFile("attachment[2]", "filename-3.txt", "text/plain", "3".getBytes());
        MockMultipartFile file4 = new MockMultipartFile("attachment[3]", "filename-4.txt", "text/plain", "4".getBytes());
        MockMultipartFile file5 = new MockMultipartFile("attachment[4]", "filename-5.txt", "text/plain", "5".getBytes());

        MockMultipartFile caseDetailsJson = new MockMultipartFile("caseDetails", "", "application/json","{\"exampleAttr\": \"someValue\"}".getBytes());

        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(uploadController).build();
        mockMvc.perform(MockMvcRequestBuilders.fileUpload("/submitCase")
                .file(file1)
                .file(file2)
                .file(file3)
                .file(file4)
                .file(file5)
                .file(caseDetailsJson))
                    .andDo(MockMvcResultHandlers.print())
                    .andExpect(MockMvcResultMatchers.content().string("{\"success\":\"true\"}"))
                    .andReturn();
    }

    @Configuration
    static class TestConfig {

        @Bean
        public UploadController uploadController() {
            return new UploadController();
        }
    }
}

Please note, in UploadControllerTest the JSON data must be wrapped in a MockMultipartFile - equivalent to the uploaded files. Make sure, that jackson-core and jackson-databind are available on the classpath.

seb.wired
  • 456
  • 1
  • 3
  • 12
  • Hey, I tried using that, but i also need to send json data for the CaseDetails parameter. I cant do that using fileUpload. Any ideas? – user3762085 Feb 26 '19 at 11:17
  • I updated my answer. From the perspective of Spring `MockMvc` 4.3.0, JSON in context of a multipart/form-data request is treated in the same way as files: wrap the data in a `MockMultipartFile`. I extended the example in order to point that out. Does this work for you? – seb.wired Feb 26 '19 at 20:26