spring-cloud-contract

Spring Cloud Contract: Escaping Issue with fromRequest() in Response Body


I am using Spring Cloud Contract for testing, and I have a Groovy contract test with the following response body:

message: ["method.page": "The sort fields [${fromRequest().query('sort')}] are not within the allowed values: [sortField]"]

When I use a hardcoded value wrong-sort instead of ${fromRequest().query('sort')}, the generated test has a proper assertion like this:

assertThatJson(parsedJson).field("['message']").field("['method.page']")
    .isEqualTo("The sort fields [wrong-sort] are not within the allowed values: [sortField]");

However, when using ${fromRequest().query('sort')}, the generated assertion looks like this:

assertThatJson(parsedJson).field("['message']").field("['method.page']")
    .matches("The sort fields \\\\[wrong-sort\\\\] are not within the allowed values: \\\\[sortField\\\\]");

It appears that unnecessary escaping (\\) is being added to the brackets, which causes the test to fail.

I tried: message: ["method.page": $("The sort fields [${fromRequest().query('sort')}] are not within the allowed values: [sortField]"]) but the result was the same.

How can I configure the contract to ensure the generated test passes while dynamically including the value of ${fromRequest().query('sort')}?


Solution

  • I resolved this issue using bodyMatchers {}. The problem was with an incorrect jsonPath in my initial attempt. After correcting it, this worked:

    response {
        message: [
            "method.page": "The sort fields [${fromRequest().query('sort')}] are not within the allowed values: [sortField]"
        ]
    }
    
    bodyMatchers {
        jsonPath('$.message["method.page"]', byRegex('The sort fields \\[.*\\] are not within the allowed values: \\[sortField\\]'))
    }
    

    This generated a valid test assertion:

    assertThat(parsedJson.read("$.message[\"method.page\"]", String.class))
        .matches("The sort fields \\[.*\\] are not within the allowed values: \\[sortField\\]");