I have a controller\'s method with a PUT
method, which receives multipart/form-data:
@RequestMapping(value = \"/putIn\", method = RequestMeth
This is unfortunately currently not supported in Spring MVC Test, and I don't see a work-around other than creating your own custom MockPutMultipartHttpServletRequestBuilder
and copying-n-pasting code from the standard implementation.
For what it's worth, Spring MVC also does not support PUT
requests for file uploads by default either. The Multipart resolvers are hard coded to accept only POST
requests for file uploads -- both for Apache Commons and the standard Servlet API support.
If you would like Spring to support PUT
requests in addition, feel free to open a ticket in Spring's JIRA issue tracker.
Yes, there is a way, and it's simple too!
I ran into the same problem myself. Though I was discouraged by Sam Brannen's answer, it appears that Spring MVC nowadays DOES support PUT file uploading as I could simply do such a request using Postman (I'm using Spring Boot 1.4.2). So, I kept digging and found that the only problem is the fact that the MockMultipartHttpServletRequestBuilder
returned by MockMvcRequestBuilders.fileUpload()
has the method hardcoded to "POST". Then I discovered the with()
method...
and that allowed me to come up with this neat little trick to force the MockMultipartHttpServletRequestBuilder
to use the "PUT" method anyway:
MockMultipartFile file = new MockMultipartFile("data", "dummy.csv",
"text/plain", "Some dataset...".getBytes());
MockMultipartHttpServletRequestBuilder builder =
MockMvcRequestBuilders.fileUpload("/test1/datasets/set1");
builder.with(new RequestPostProcessor() {
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
request.setMethod("PUT");
return request;
}
});
mvc.perform(builder
.file(file))
.andExpect(status().ok());
Works like a charm!
You can pass both foo
and file
Try rewrite you controller like:
@RequestMapping(value = "/putIn", method = RequestMethod.PUT)
public Foo updateFoo(
HttpServletRequest request,
@RequestPart Foo foo,
@RequestPart MultipartFile file) {
...
}
And test looks like:
MockMultipartFile file = new MockMultipartFile("file", "dummy.csv",
"text/plain", "Some dataset...".getBytes());
// application/json if you pass json as string
MockMultipartFile file2 = new MockMultipartFile("foo", "foo.txt",
"application/json", "Foo data".getBytes());
MockMultipartHttpServletRequestBuilder builder =
MockMvcRequestBuilders.multipart("/test1/datasets/set1");
builder.with(new RequestPostProcessor() {
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
request.setMethod("PUT");
return request;
}
});
mvc.perform(builder
.file(file)
.file(file2))
.andExpect(status().ok());