I have a contract that uses stringType to match a filename. The contract also specifies the matcher on type, but when I run the test on the provider side, it does a literal match. I've included the contract, the JSON that is send and a screenshot while debugging. I noticed that a TypeMatcher is initialized in the MatchingRuleGroup, but it has no fields. I'm not sure if this is correct
I tried 3 scenario's:
stringValue("bestandsid","20190219_foo_20190124.txt") --> this works
stringType("bestandsid","20190101_foo_20190124.txt") --> doesn't work, because it literally expects 20190101_foo_20190124.txt but got 20190219_foo_20190124.txt
stringType("bestandsid") --> doesn't work. It literally expects 'string' but got 20190219_foo_20190124.txt
At the provider I use
pact-jvm-provider-spring_2.12 - Version 3.6.2
At the consumer I use
pact-jvm-consumer-junit_2.12 - Version 3.6.2
pact-jvm-consumer-java8_2.12 - Version 3.6.2
CONTRACT:
{
"consumer": {
"name": "Consumer-event"
},
"provider": {
"name": "Provider"
},
"messages": [
{
"description": "A message notifying a newly available foo file",
"metaData": {
"bestandstype": "foo",
"Content-Type": "application/json"
},
"contents": {
"headers": {
"bestandstype": "foo",
"Content-Type": "application/json"
},
"payload": {
"bestandstype": "foo",
"bestandsid": "string"
}
},
"providerStates": [
{
"name": "A new FOO file is extracted"
}
],
"matchingRules": {
"body": {
"$.payload$.bestandsid": {
"matchers": [
{
"match": "type"
}
],
"combine": "AND"
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "3.0.0"
},
"pact-jvm": {
"version": "3.6.2"
}
}
}
ACTUAL EVENT
{
"headers": {
"Content-Type": "application/json",
"bestandstype": "foo",
"id": "6838a619-efb7-6867-28bc-eb24609aa980",
"timestamp": 1560410882485
},
"payload": {
"afleidDatum": null,
"bestandsid": "20190219_foo_20190124.txt",
"bestandstype": "foo",
"bron": null,
"planDatum": null,
"planType": "BAR"
}
}
CONSUMER CONTRACT
@Pact(provider = "DonnaFileshareReader", consumer = "DpcAdapter-event")
public MessagePact eventNewDpcResource(MessagePactBuilder builder) {
Map<String, String> metadata = new HashMap<>();
metadata.put("Content-Type", "application/json");
metadata.put("bestandstype", "dpc");
PactDslJsonBody body = new PactDslJsonBody();
body.object("headers")
.stringValue("bestandstype", "dpc")
.stringValue("Content-Type", "application/json")
.closeObject();
payload = new PactDslJsonBody();
payload.stringValue("bestandstype", "dpc")
.stringValue("bestandsid", EXAMPLE_DPC_FILE_NAME)
.closeObject();
body.object("payload", payload);
return builder.given("A new DPC file is extracted")
.expectsToReceive("A message notifying a newly available dpc file")
.withMetadata(metadata)
.withContent(body)
.toPact();
}
ERROR:
Verifying a pact between DpcAdapter-event and DonnaFileshareReader
Given A new FOO file is extracted
A message notifying a newly available foo file
2019-06-13 09:56:54.144 INFO [bar,,,] 7427 --- [ main] org.reflections.Reflections : Reflections took 9011 ms to scan 388 urls, producing 275 keys and 35566 values
generates a message which
has a matching body (FAILED)
has matching metadata (OK)
Failures:
0) A message notifying a newly available foo file generates a message which has a matching body
$.payload.bestandsid -> Expected 'string' but received '20190219_foo_20190124.txt'
I expect that stringType matches on the String type.
Solved.
By changing the contract to 1 PactDslJsonBody() instead of using body(object,payload).
New contract:
body.object("headers")
.stringValue("bestandstype", "foo")
.stringValue("Content-Type", "application/json")
.closeObject();
body.object("payload")
.stringValue("bestandstype", "foo")
.stringType("bestandsid", EXAMPLE_FOO_FILE_NAME)
.closeObject();
New message construction in the test (although you can also construct the PactDslJsonBody as in the original question and use that)
JSONObject resourceDetail = (JSONObject)body.getBody();
JSONObject payload = resourceDetail.getJSONObject("payload");
Message<byte[]> pactMessage = MessageBuilder
.withPayload(payload.toString().getBytes())
.copyHeaders(messageProvider.getMetadata())
.build();