3

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?

riorio
  • 6,500
  • 7
  • 47
  • 100
  • 1
    Aren't you trying to do something that should not be done? I think your test shows that your API is wrong because, if I recall correctly, DELETE should not have BODY. If I am wrong, please correct me. – Pijotrek Jan 10 '19 at 14:05

2 Answers2

0

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.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
0

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.