I'm trying to define a CDC contract using Spring-Cloud-Contract like this:
org.springframework.cloud.contract.spec.Contract.make {
request {
method 'GET'
url $(client(~/\/categories\?publication=[a-zA-Z-_]+?/), server('/categories?publication=DMO'))
}
response {
status 200
headers {
header('Content-Type', 'application/json;charset=UTF-8')
}
body """\
[{
"code": "${value(client('DagKrant'), server(~/[a-zA-Z0-9_-]*/))}",
"name": "${value(client('De Morgen Krant'), server(~/[a-zA-Z0-9_\- ]*/))}",
"sections" : []
},
{
"code": "${value(client('WeekendKrant'), server(~/[a-zA-Z0-9_-]*/))}",
"name": "${value(client('De Morgen Weekend'), server(~/[a-zA-Z0-9_\- ]*/))}",
"sections" : [
{
"id" : "${value(client('a984e824'), server(~/[0-9a-f]{8}/))}",
"name" : "${value(client('Binnenland'), server(~/[a-zA-Z0-9_\- ]*/))}"
}
]
}]
"""
}
}
In the generated tests, this results in the following assertions:
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).array().contains("code").matches("[a-zA-Z0-9_-]*");
assertThatJson(parsedJson).array().array("sections").contains("id").matches("([0-9a-f]{8})?");
assertThatJson(parsedJson).array().array("sections").contains("name").matches("[a-zA-Z0-9_\\- ]*");
assertThatJson(parsedJson).array().contains("name").matches("[a-zA-Z0-9_\\- ]*");
But in my tests I want to allow that the sections array is empty, like the first example. Now, if my test implementation returns an empty sections array, the generated tests fail because it cannot find the sections' id for an empty array.
Parsed JSON [[{"code":"WeekendKrant","name":"De Morgen Weekend","sections":[]}]]
doesn't match the JSON path [$[*].sections[*][?(@.id =~ /([0-9a-f]{8})?/)]]
I also tried with optional(), but the only difference is that the regex includes a '?' at the end. The JSON assertion still fails.
In the stubs, both results are returned, but for the test, I want the test to succeed for both, too. Are the test assertions purely generated on the last occurence of each attribute? Is there no possibility to have something like 'optional()' on the array?
It wasn't possible to do additional checks like this up till version 1.0.3.RELEASE. Since that version you can provide additional matchers - http://cloud.spring.io/spring-cloud-static/spring-cloud-contract/1.0.3.RELEASE/#_dynamic_properties_in_matchers_sections . You can match
byType
with additional check related to size.Taken from the docs:
And example:
and example of a generated test (part for asserting sizes)