Skip to content

Problems basing documentation on MockMVC. #41

Closed
@davidgoate

Description

@davidgoate

First of all, thanks for the work so far on this project. I heard about this on the recent Spring webinar and I was excited to give it a try. I'd like to suggest a possible enhancement, but, I'm not really sure whether this goes against the basic principle of this project.

When using Spring Boot (or for any situations where it's just as easy to get a full embedded container up and running) there is arguably no need for MockMVC, and I believe it actually can do harm.

I followed one of the sample projects using Spring Boot and initialise MockMVC like this:

    @Autowired
    private WebApplicationContext context;
    private MockMvc mockMvc;

    @Before
    public void setUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
                .apply(new RestDocumentationConfigurer())
                .alwaysDo(document(getDocumentationName()))
                .build();
    }

However - and it could very easily be a lack of my understanding of MockMVC - I feel that there are issues with this:

  • When creating a MockMVC instance from a fully built WebApplicationContext it appears that not all filters are copied (for example Spring Security filters).
  • Other important configuration (such as the context path or some error handling logic) isn't used.

This means that if an app is always run on a path such as "/api/" e.g. "https://myhost/api/" there doesn't seem to be a way for the documentation to be aware of the "/api" path meaning all sample CURL requests won't work.

Furthermore, due to the lack of filters I have observed differences in actual runtime behaviour when compared with test behaviour in terms of response headers and error handling. E.g.

In tests if I do something like:

getMockMvc()
                .perform(get("/no-such-endpoint").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isNotFound());

I get simply

HTTP/1.1 404 Not Found

However, against the real app I get:

curl http://localhost:8080/api/no-such-endpoint -i -H "Accept: application/json"
HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
X-Application-Context: application:development
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 24 Mar 2015 15:11:05 GMT

{
  "timestamp" : 1427209865283,
  "status" : 404,
  "error" : "Not Found",
  "message" : "No message available",
  "path" : "/api/no-such-endpoint"
}

I appreciate that the reason that none of the Spring Security headers are there is because of the filters not being present. But, there are also other potentially important differences such as the lack of response body.

I feel that an important attribute of documenting the API is that the documentation is as accurate as possible. This is why I like the idea of documentation being produced by tests.

I don't fully understand why these differences happen, but my suggestion would be that if at all possible this project could provide a special RestTemplate, e.g. DocumentingRestTemplate that could be used to make requests (instead of MockMvc) against a real embedded container and this way the results should be more accurate since it is a real version of the app.

Any thoughts or comments welcome and thanks so much for the work so far!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions