ismail
05/19/2025, 12:00 PMismail
05/19/2025, 12:07 PMTo help answer this, we’d need a reproducible example (a pact file and OAS)
A screenshot of the UI in PactFlow would also be ideal.
Also, move this thread to #CLS16AVEE if you don’t mind, as it’s not related to the Pact Broker (the open source derivative of PactFlow)@Matt (pactflow.io / pact-js / pact-go) here is the screenshots:
Matt (pactflow.io / pact-js / pact-go)
Matt (pactflow.io / pact-js / pact-go)
ismail
05/19/2025, 1:36 PMI see matchers (which aren't used in BDCT)is ther any specific matcher for BDCT? here is the actual implementation :
public function testAll()
{
$servicesPath = '/api/internal/services';
$config = (new MockServerEnvConfig())
->setConsumer($this->pactConsumerName)
->setPactSpecificationVersion('4.0')
->setProvider(self::PROVIDER_NAME)
->setPactDir(__DIR__ . '/pacts');
$interaction = new InteractionBuilder($config);
$interaction
->given('OfferService list is not empty')
->uponReceiving('json-array with OfferService objects')
->with(
(new ConsumerRequest())
->setMethod('GET')
->setPath($servicesPath)
->addHeader('Authorization', new Regex('^Bearer\\s.+'))
)
->willRespondWith(
(new ProviderResponse())
->setStatus(200)
->setHeaders([
'Content-Type' => new Regex('application/json(;\\s?charset=.*)?')
])
->setBody(
[
"items" => [
["id" => "17575ed0-9533-4000-a967-9011ffc6ff94", "name" => "Curb", "isActive" => true],
["id" => "df9095b8-63af-4e5c-8e52-c6e9bd1c8c78", "name" => "Premise", "isActive" => true],
],
"totalCount" => 2,
]
)
);
$response = HttpClient::create()->request('GET', $config->getBaseUri() . $servicesPath, ['auth_bearer' => 'CthulhuFhtagn']);
$this->assertSame(200, $response->getStatusCode());
$body = $response->toArray();
$this->assertIsArray($body);
$this->assertArrayHasKey('items', $body);
$this->assertIsArray($body['items']);
$this->assertNotEmpty($body['items']);
$item = $body['items'][0];
$this->assertArrayHasKey('id', $item);
$this->assertNotEmpty($item['id']);
$this->assertIsString($item['id']);
$this->assertTrue(Uuid::isValid($item['id']));
$this->assertArrayHasKey('name', $item);
$this->assertNotEmpty($item['name']);
$this->assertIsString($item['name']);
$this->assertArrayHasKey('isActive', $item);
$this->assertNotEmpty($item['isActive']);
$this->assertIsBool($item['isActive']);
$this->assertArrayHasKey('totalCount', $body);
$this->assertIsInt($body['totalCount']);
$this->assertEquals(count($body['items']), $body['totalCount']);
$verified = $interaction->verify();
$this->assertTrue($verified, 'Pact verification failed.');
// Add matching rules manually
$pactPath = __DIR__ . '/pacts/' . $this->pactConsumerName . '-' . self::PROVIDER_NAME . '.json';
$pact = json_decode(file_get_contents($pactPath), true);
$pact['interactions'][0]['response']['body'] = $pact['interactions'][0]['response']['body']['content'];
$pact['interactions'][0]['response']['matchingRules'] = [
'header' => [
'Content-Type' => [
'matchers' => [[
'match' => 'regex',
'regex' => 'application/json(;\\s?charset=.*)?',
]],
'combine' => 'AND',
],
],
'body' => [
'$.items' => [
'matchers' => [['match' => 'type', 'min' => 1]],
],
'$.items[*].id' => [
'matchers' => [
['match' => 'type'],
['match' => 'notEmpty'],
['match' => 'regex', 'regex' => '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$'],
],
],
'$.items[*].name' => [
'matchers' => [['match' => 'type'], ['match' => 'notEmpty']],
],
'$.items[*].isActive' => [
'matchers' => [['match' => 'type']],
],
'$.totalCount' => [
'matchers' => [['match' => 'type']],
['match' => 'notEmpty'],
],
],
];
$uploadResult = $this->pactFlowService->uploadContract($this->pactConsumerName, self::PROVIDER_NAME,
$this->version, $this->branch, json_encode($pact));
$this->assertTrue($uploadResult);
}
are those matchers correct?Matt (pactflow.io / pact-js / pact-go)
$response = HttpClient::create()->request('GET', $config->getBaseUri() . $servicesPath, ['auth_bearer' => 'CthulhuFhtagn']);
This means
See also this best practice guide.
2. // Add matching rules manually
Why are you manually adding matchers? This is a super advanced case that basically nobody should be doing (the only case I can really think of is if there is a bug in Pact, or you are not using Pact to generate the contract in the first place).
3. As noted above, matchers are not relevant for BDCT anyway. In BDCT, the request/response body is compared against the OAD schema. The “matchers” here are essentially the OAD schema.
4. The assertions aren’t testing your API client, they’re checking the mock server did it’s job. This is only testing Pact, which isn’t useful
i.e.
$body = $response->toArray();
$this->assertIsArray($body);
$this->assertArrayHasKey('items', $body);
$this->assertIsArray($body['items']);
$this->assertNotEmpty($body['items']);
$item = $body['items'][0];
...
Just asserts that the mock server returned what you told it to.
5. Uploading the contract within the unit test isn’t good practice
You should use a separate CI step to do thisismail
05/20/2025, 7:04 AM