I have a controller's method with a PUT
method, which receives multipart/form-data:
@RequestMapping(value = "/putIn", method = RequestMethod.PUT)
public Foo updateFoo(HttpServletRequest request,
@RequestBody Foo foo,
@RequestParam("foo_icon") MultipartFile file) {
...
}
and I want to test it using MockMvc
. Unfortunately MockMvcRequestBuilders.fileUpload
creates essentially an instance of MockMultipartHttpServletRequestBuilder
which has a POST
method:
super(HttpMethod.POST, urlTemplate, urlVariables)
EDIT:
Surely I can I can not create my own implementation of MockHttpServletRequestBuilder
, say
public MockPutMultipartHttpServletRequestBuilder(String urlTemplate, Object... urlVariables) {
super(HttpMethod.PUT, urlTemplate, urlVariables);
super.contentType(MediaType.MULTIPART_FORM_DATA);
}
because MockHttpServletRequestBuilder
has a package-local constructor.
But I'm wondering is there any more convenient Is any way to do this, may be I missed some existent class or method for doing this?
MockMVC class is part of Spring MVC test framework which helps in testing the controllers explicitly starting a Servlet container. In this MockMVC tutorial, we will use it along with Spring boot's WebMvcTest class to execute Junit testcases which tests REST controller methods written for Spring boot 2 hateoas example.
step1: User enters values in 1st jsp step2: values go to controller1. java step3: i need to be able to capture the same values in 2nd jsp step4: pass on the same value to controller2. java. I am successful with step1 and step2.
standaloneSetup() allows to register one or more controllers without the need to use the full WebApplicationContext . @Test public void testHomePage() throws Exception { this.mockMvc.perform(get("/")) .andExpect(status().isOk()) .andExpect(view().name("index")) .andDo(MockMvcResultHandlers.print()); }
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.multipart("/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().isOk());
Works like a charm!
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.
Translating @HammerNl answer for Kotlin. This worked for me.
val file = File("/path/to/file").readBytes()
val multipartFile = MockMultipartFile("image", "image.jpg", "image/jpg", file)
val postProcess = RequestPostProcessor { it.method = "PUT"; it}
mockMvc.perform(
MockMvcRequestBuilders.multipart("/api/image/$id")
.file(multipartFile)
.with(postProcess))
.andExpect(MockMvcResultMatchers.status().isOk)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With