Support RestAssuredMockMvc

Issue #181 resolved
Former user created an issue

If you try to use MockMvc validator in RestAssuredMockMvc environment:

        given()
                .contentType(MediaType.APPLICATION_JSON_VALUE)
        .when()
                .post("xxx")
        .then()
                .expect(openApi().isValid("api.json));

you get:

java.lang.IllegalStateException: Cannot call getReader() after getInputStream() has already been called for the current request

    at org.springframework.mock.web.MockHttpServletRequest.getReader(MockHttpServletRequest.java:716)
    at com.atlassian.oai.validator.mockmvc.MockMvcRequest.getReader(MockMvcRequest.java:119)
    at com.atlassian.oai.validator.mockmvc.MockMvcRequest.getBody(MockMvcRequest.java:100)
    at com.atlassian.oai.validator.mockmvc.MockMvcRequest.of(MockMvcRequest.java:91)
    at com.atlassian.oai.validator.mockmvc.OpenApiMatchers.lambda$isValid$0(OpenApiMatchers.java:56)

This happens because RestAssuredMockMvc calls getInputStream() on MockHttpServletRequest, and MockMvc validator calls getReader() on the same MockHttpServletRequest, which can't be done according to servlet specs:

Either this method
     * or {@link #getInputStream} may be called to read the body, not both.

Comments (6)

  1. Darrell King

    The MockMvc validator works with RestAssured when you use a version of Spring prior to 5.1. SPR-16499 changed the behaviour of MockHttpServletRequest to only disallow calls to calls getInputStream() and getReader()

    Unfortunately simply replacing the call to getReader() with getInputStream() causes us to run into the related SPR-16505 issue which changed the behaviour of MockHttpServletRequest to only allow the InputStream to only be read once.

  2. Sven Döring

    I can reproduce the error in a unit test.

    However it is not that simple to correct that behaviour.

    The method MockHttpServletRequest#getContentAsByteArray() was introduced in Spring 5. The OpenApiMatchers is supporting Spring 4. Changing that would break the backwards compability. All Spring Boot users prior v2.1.0 (released ~3 months ago) would have failing tests.

    There are several options.

    Any other ideas?

  3. Darrell King

    I don't want to break backwards compatibility either and those are also the options I came up with.

    My favoured approach:

    • Rename the current pre Spring 5.1 supporting module to swagger-request-validator-mockmvc to swagger-request-validator-mockmvc-legacy (following the naming convention from the spring-boot-legacy module that adds Servlet 2.5 support to to Spring Boot 2 and this discussion at Togglz)
    • Create a new swagger-request-validator-mockmvc module that supports Spring 5.1 onwards

    pull request #121 implements these changes

  4. James Navin

    Issue should be resolved in v2.2.0

    As described in the PR - if you are using Spring Boot < 2.1 (Spring < 5.1) you will need to change your dependency to swagger-request-validator-mockmvc-legacy

  5. Log in to comment