8
votes

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();
        }
    }
}
1
Do you want the request or response?M. Deinum
@M.Deinum request. And the response print is out of box now.Yugang Zhou

1 Answers

4
votes

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