I'm using spring-test-mvc to test my controller, but I can't find a way to print request body which is very inconvenient.
with MockMvcResultHandlers.print()
mvc.perform(put("/payment/1234")
.content("{\"amount\":2.3")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print());
I found some body information but don't find the body part:
MockHttpServletRequest:
HTTP Method = PUT
Request URI = /payment/1234
Parameters = {}
Headers = {Content-Type=[application/json]}
Handler:
Type = com.restbucks.ordering.rest.PaymentResource
Method = public org.springframework.hateoas.Resource<com.restbucks.ordering.domain.Payment> com.restbucks.ordering.rest.PaymentResource.handle(com.restbucks.ordering.commands.MakePaymentCommand)
Async:
Async started = false
Async result = null
Update
After reading some source codes, it seems that I should extends MockMvcResultHandlers to add some print items?
//PrintingResultHandler.java
protected void printRequest(MockHttpServletRequest request) throws Exception {
this.printer.printValue("HTTP Method", request.getMethod());
this.printer.printValue("Request URI", request.getRequestURI());
this.printer.printValue("Parameters", getParamsMultiValueMap(request));
this.printer.printValue("Headers", getRequestHeaders(request));
// add body print?
}
Update Proof of Concept codes:
public static class CustomMockMvcResultHandlers {
public static ResultHandler print() {
return new ConsolePrintingResultHandler();
}
/**
* Have to copy this class from spring
*/
private static class ConsolePrintingResultHandler extends PrintingResultHandler {
public ConsolePrintingResultHandler() {
super(new ResultValuePrinter() {
@Override
public void printHeading(String heading) {
System.out.println();
System.out.println(String.format("%20s:", heading));
}
@Override
public void printValue(String label, Object value) {
if (value != null && value.getClass().isArray()) {
value = CollectionUtils.arrayToList(value);
}
System.out.println(String.format("%20s = %s", label, value));
}
});
}
@Override
protected void printRequest(MockHttpServletRequest request) throws Exception {
super.printRequest(request);
getPrinter().printValue("Body", getContentAsString(request));
}
private String getContentAsString(MockHttpServletRequest request) throws IOException {
BufferedReader reader = request.getReader();
StringBuilder builder = new StringBuilder();
String aux;
while ((aux = reader.readLine()) != null) {
builder.append(aux);
}
return builder.toString();
}
}
}
Simply put, the @RequestBody annotation maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object.
To retrieve the body of the POST request sent to the handler, we'll use the @RequestBody annotation, and assign its value to a String. This takes the body of the request and neatly packs it into our fullName String.
Annotation Type RequestBody Annotation indicating a method parameter should be bound to the body of the web request. The body of the request is passed through an HttpMessageConverter to resolve the method argument depending on the content type of the request.
public MockHttpServletRequestBuilder servletPath(String servletPath) Specify the portion of the requestURI that represents the path to which the Servlet is mapped. This is typically a portion of the requestURI after the context path.
I believe this will now be possible with Spring Framework 5.0 M3:
The print() and log() methods in Spring MVC Test now print the request body if the character encoding has been set in the mock request.
Based on this Jira ticket
Also mentioned in the release notes
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