Reputation: 2326
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
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
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