Can't get provider to recognize matchers in pact
See original GitHub issueThis could totally be user error as I’m somewhat new to this, but for the life of me I can not figure out how to get the provider to verify a pact without it trying to do exact matching.
I have a consumer which generates this pact:
{
"consumer": {
"name": "rest-fights"
},
"interactions": [
{
"comments": {
"testname": "io.quarkus.sample.superheroes.fight.client.VillainConsumerContractTests.helloVillains()",
"text": [
]
},
"description": "A hello request",
"key": "2ec6e2e8",
"pending": false,
"request": {
"headers": {
"Accept": [
"text/plain"
]
},
"method": "GET",
"path": "/api/villains/hello"
},
"response": {
"body": {
"content": "Hello villains!",
"contentType": "text/plain",
"contentTypeHint": "DEFAULT",
"encoded": false
},
"headers": {
"Content-Type": [
"text/plain"
]
},
"matchingRules": {
"body": {
"$": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
},
"header": {
"Content-Type": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "text/plain"
}
]
}
}
},
"status": 200
},
"type": "Synchronous/HTTP"
}
],
"metadata": {
"pact-jvm": {
"version": "4.3.14"
},
"pactSpecification": {
"version": "4.0"
}
},
"provider": {
"name": "rest-villains"
}
}
It is generated by a JUnit 5 test (au.com.dius.pact.consumer:junit5:4.3.14
)
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(
providerName = "rest-villains",
pactVersion = PactSpecVersion.V4,
hostInterface = "localhost",
// Make an assumption and hard-code the Pact MockServer to be running on port 8081
// I don't like it but couldn't figure out any other way
port = "8081"
)
public class VillainConsumerContractTests {
@Pact(consumer = "rest-fights")
public V4Pact helloPact(PactDslWithProvider builder) {
return builder
.uponReceiving("A hello request")
.path(VILLAIN_HELLO_URI)
.method(HttpMethod.GET)
.headers(HttpHeaders.ACCEPT, MediaType.TEXT_PLAIN)
.willRespondWith()
.matchHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN, MediaType.TEXT_PLAIN)
.status(Status.OK.getStatusCode())
.body(PactDslRootValue.stringType(DEFAULT_HELLO_RESPONSE))
.toPact(V4Pact.class);
}
@Test
@PactTestFor(pactMethod = "helloPact")
void helloVillains() {
runHelloVillains(); // What this does is unimportant here. It works and generates the pact pasted above
}
}
The pact is published to pactflow.io.
On the provider side I have this (au.com.dius.pact.provider:junit5:4.3.14
):
@Provider("rest-villains")
@PactBroker(url = "https://myname.pactflow.io")
@EnabledIfSystemProperty(named = "pactbroker.auth.token", matches = ".+", disabledReason = "pactbroker.auth.token system property not set")
public class ContractVerificationTests {
@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void pactVerificationTestTemplate(PactVerificationContext context) {
context.verifyInteraction();
}
@BeforeEach
void beforeEach(PactVerificationContext context) {
context.setTarget(new HttpTestTarget("localhost", 8081));
}
@PactBrokerConsumerVersionSelectors
public static SelectorBuilder consumerVersionSelectors() {
return new SelectorBuilder()
.branch(System.getProperty("pactbroker.consumer.branch", "main"));
}
}
When I run the verification I’m getting this:
Verifying a pact between rest-fights (1.0) and rest-villains
Notices:
1) The pact at https://myname.pactflow.io/pacts/provider/rest-villains/consumer/rest-fights/pact-version/ed93e91f94fe8ea4404bb1c08318b77005f1f432 is being verified because the pact content belongs to the consumer version matching the following criterion:
* latest version from branch 'main' (1.0)
[from Pact Broker https://myname.pactflow.io/pacts/provider/rest-villains/consumer/rest-fights/pact-version/ed93e91f94fe8ea4404bb1c08318b77005f1f432/metadata/c1tdW2JdPW1haW4mc1tdW2xdPXRydWUmc1tdW2N2XT0xNg]
A hello request
Test Name: io.quarkus.sample.superheroes.fight.client.VillainConsumerContractTests.helloVillains()
Comments:
08:35:29 DEBUG [io.qu.sa.su.vi.re.VillainResource] (executor-thread-0) Hello Villain Resource
returns a response which
has status code 200 (OK)
includes headers
"Content-Type" with value "text/plain" (FAILED)
has a matching body (FAILED)
Failures:
1) Verifying a pact between rest-fights and rest-villains - A hello request includes headers "Content-Type" with value "[text/plain]"
1.1) header: Expected 'text/plain;charset=UTF-8' to match 'text/plain'
1.2) body: / Expected body 'Hello villains!' to match 'Hello Villain Resource' using equality but did not match
It looks like its doing exact matching on the header and body, even though the pact has matching rules where
- The
Content-Type
header should containtext/plain
, not be equal totext/plain
- The body should match any
String
and shouldn’t be trying to verify an exactString
Am I doing something wrong here or missing something? Or is something not working the way it should?
On the consumer I also tried using PactSpecVersion.V3
instead of PactSpecVersion.V4
but got the same result.
The entire source code of the consumer & provider is available:
Issue Analytics
- State:
- Created a year ago
- Comments:10 (3 by maintainers)
Top GitHub Comments
That makes sense, essentially you are stating the body must not be empty.
I was actually able to get this work by doing some stuff in the
@BeforeEach
method. At that point the CDI context is fully available.