FreeOnGoo
FreeOnGoo

Reputation: 878

How to format Spring REST Docs in response body with mockMvc

I write my API documentation with Spring REST Docs.

Code example:

@Override
public void getById(String urlTemplate, PathParametersSnippet pathParametersSnippet, Object... urlVariables) throws Exception {
    resultActions = mockMvc.perform(get(urlTemplate, urlVariables)
            .principal(principal)
            .contentType(APPLICATION_JSON))
            .andExpect(status().isOk())
            .andDo(print());

    // do..
}

But the problem is that the result of the test is answered in one line. And understanding the structure of the returned data is very difficult.

Response example:

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {"creator":null,"modifier":null,"modificationTime":null,"creationTime":null,"id":100,"deleted":false,"name":"Name","description":null,"report":[{"creator":"System","modifier":"System","modificationTime":"2019-01-30T14:21:50","creationTime":"2019-01-30T14:21:50","id":1,"name":"Form name","reportType":{"creator":"System","modifier":"System","modificationTime":"2019-01-30T14:21:50","creationTime":"2019-01-30T14:21:50","id":1,"deleted":false,"name":"Raport"},"unmodifiable":true}]}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Further, I generate documentation from the answer received and in the documentation also unformatted JSON

What am I doing wrong? How to enable formatting for json?

Upvotes: 5

Views: 5957

Answers (2)

Andy Wilkinson
Andy Wilkinson

Reputation: 116051

If you're not in a position to configure your application to produce pretty-printed responses, you can have REST Docs do it for you prior to them being documented. This is described in the Customizing Requests and Responses section of the documentation:

Preprocessing is configured by calling document with an OperationRequestPreprocessor, and/or an OperationResponsePreprocessor. Instances can be obtained using the static preprocessRequest and preprocessResponse methods on Preprocessors. For example:

this.mockMvc.perform(get("/")).andExpect(status().isOk())
    .andDo(document("index", preprocessRequest(removeHeaders("Foo")), 
            preprocessResponse(prettyPrint()))); 

In the case above the request is being preprocessed to remove a Foo header and the response is being preprocessed so that it appears pretty-printed.

Upvotes: 12

Andrey Nikolaev
Andrey Nikolaev

Reputation: 21

You can try get ResultActions object from mockMvc and than get MockHttpServletResponse object. After that you can get all the values of the fields that came in response. In this case, you will not need to parse the string.

resultActions = mockMvc.perform(get(urlTemplate, urlVariables)
    .principal(principal)
    .contentType(APPLICATION_JSON))
    .andExpect(status().isOk())
    .andDo(print());

MockHttpServletResponse content = resultActions.andReturn().getResponse();

Also you can transform MockHttpServletResponse object data to json. IUf you use Jacson, than write your custom serializer for this object, add it to MockHttpServletResponse and register in ObjectMapper.

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(MockHttpServletResponse.class, CustomSerializer.class);
mapper.registerModule(module);
String jsonResult = mapper.writeValueAsString(content);

CustomSerializer should extends StdSerializer<MockHttpServletResponse> and override serialize method.

Upvotes: 0

Related Questions