Mockmvc for a DELETE method that accepts a Multipart file

Viewed 1399

I'm trying to write a unit test for a controller that has a DELETE method that should accept a File and a text param.

I know I can do a simple delete like that:

    MvcResult result = mockMvc.perform(MockMvcRequestBuilders.delete(
            "/deletecat/catname/Oscar"))
            .andExpect(status().isOK)
            .andReturn();

And I can do a POST to a Multipart file like that:

MockMultipartFile multipartFile = new MockMultipartFile("file", new FileInputStream(TEST_RESOURCES_FOLDER + "Cats.csv"));
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.multipart("/uploadcats")
   .file(multipartFile)
   .param("ownerName", "Austin Powers"))
   .andExpect(status().isOk())
   .andReturn();

But when I tried to combine them together and wrote this:

 MvcResult result = mockMvc.perform(
            MockMvcRequestBuilders.delete(
                    "/deletecats", 
                    multipartFile, "Austin Powers"))
            .andExpect(status().isOk())
            .andReturn();

I get the following error of "Current request is not a multipart request":

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Current request is not a multipart request

Is it possible that the HTTP protocol is not supporting to do a DELETE with Multipart file?

2 Answers

It seems that MockMultipartHttpServletRequestBuilder only supports POST requests, the constant representing HTTP method is hard-coded in the constructors. This is strange because at least POST and PUT are commonly used with multipart.

I'm afraid that with current version you would have to fork the class and change the HTTP method yourself.

I personally would say that this is wrong from API design perspective.

REST is heavily working with resources and therefore with their dedicated identifiers e.g.

get /entities for getting a list of entities get /entities/{entity-id} for getting a single entity

same pattern I would apply for delete: Adressing the resource by identifier.

Related