px06
px06

Reputation: 2326

"The current request is not a multipart request" when trying to test with MockMvc without uploading any file

I want to test a RequestMapping which takes some information about an item and then persists it, it also allows for images to be uploaded. However, the image uploading is not mandatory and my HTML form is using: enctype="multipart/form-data". I am trying to test the controller without actually uploading any files, the controller looks like this:

@RequestMapping(value="/admin/upload", method=RequestMethod.POST)
public ModelAndView addItem(
        @RequestParam(value="id", required=true) Integer id,
        @RequestParam(value="name", required=true) String name,
        @RequestParam(value="image", required=false) MultipartFile file,
        ) throws IOException {

    // some stuff here

    ModelAndView mov = new ModelAndView();
    return mov;

}

Even though I've set the required flag to be false I am getting the issue of a missing parameter, but more importantly, is it possible to send headers in the mockMvc request which would allow me to test this mapping without the need for uploading any images?

    mockMvc.perform(post("https://localhost/store-admin/items/itemAddSubmit")
            .param("id", 1)
            .param("name", "testname").with(csrf()))
            .andDo(print());

Upvotes: 2

Views: 2779

Answers (2)

degreesightdc
degreesightdc

Reputation: 186

Very important to note - if the [@RequestParam that accepts the file] on your REST endpoint doesn't have a "value=" attribute set, it will also throw the same type of an error when running a mock test. You could have ignored the "value" attribute when running the solution in prod and not experienced any error, but doing so would prevent you from running a test and injecting in the file programmatically.

Ex:

@RequestParam(value="file") final MultipartFile file,

Your question already showed this properly, but I want to document this answer for users in the future who may, like myself, overlook such a small detail.

Cheers

Upvotes: 1

Harshil Sharma
Harshil Sharma

Reputation: 2035

For multipart request you need to use fileUpload method instead of get, post or whatever.

Update your code as follows -

mockMvc.perform(fileUpload("https://localhost/store-admin/items/itemAddSubmit")
            .param("id", 1)
            .param("name", "testname").with(csrf()))
            .andDo(print());

To actually send a file use the file function with fileUpload as shown below -

mockMvc.perform(fileUpload("https://localhost/store-admin/items/itemAddSubmit")
            .file(myMockMultipartFile)
            .param("id", 1)
            .param("name", "testname").with(csrf()))
            .andDo(print());

where myMockMultipartFile is a MockMultipartFile object.

Upvotes: 3

Related Questions