javaspring-bootgroovyspring-cloud-contract

Spring Cloud Contract, body and execute method is not validating the response


I have the following spring cloud contract:

package contracts.teams

import org.springframework.cloud.contract.spec.Contract

Contract.make {
    name"d Find team roles by filters"
    description "Find team roles by filters"

    request {
        method "POST"
        url "api/team/findTeamRolesByFilters"
        headers {
            contentType applicationJson()
            accept applicationJson()
            header"Authorization", execute('bearerOfAccessToken()')
        }
        body execute('getRequestForFindTeamRolesByFilters()')
    }

    response {
        status OK()
        headers {
            contentType applicationJson()
        }
        body execute('getResponseForFindTeamRolesByFilters()')
    }
}

I call the getResponseForFindTeamRolesByFilters() at the response in order to generate a dynamic response from the server. The reason could for example be an auto generated id that is coming from the DB. The generated string from the getResponseForFindTeamRolesByFilters() is a valid JSON that unfortunately is ignored and returns always true when the test run.

I have noticed this when I replace the execute method with a static response like the following one:

"""
{
   "success": "false"
}
"""

In this case the response is being validated correctly and fails the test in case it does not match. What I said is being confirmed by the test generated code as it can be seen here:

// then:
            assertThat(response.statusCode()).isEqualTo(200);
            assertThat(response.header("Content-Type")).matches("application/json.*");

        // and:
            DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
            getResponseForFindTeamRolesByFilters();

As you can see there is no assertion. It simply calls the method that generates the json.

How am I supposed to make the test check the dynamic json response? Thank you!


Solution

  • I call the getResponseForFindTeamRolesByFilters() at the response in order to generate a dynamic response from the server.

    You should not do it. Contract tests should not access the database.

    For the consumer you should do

    request {
            method "POST"
            url "api/team/findTeamRolesByFilters"
            headers {
                contentType applicationJson()
                accept applicationJson()
                header"Authorization", execute('bearerOfAccessToken()')
            }
            body $(producer(execute('getRequestForFindTeamRolesByFilters()')), consumer("some value to be put on the consumer side"))
        }
    

    For the producer

    response {
        status OK()
        headers {
            contentType applicationJson()
        }
        body $(producer(execute('getResponseForFindTeamRolesByFilters()')), consumer("something in the stub"))
    }