Skip to content

Pact Contract: Ensure Array Contains Specific Entry #1868

@romanmusii

Description

@romanmusii

I'm trying to define a contract where the producer returns an array of objects, and one of the objects in that array must match a specific pattern.

For example, the producer response might look like this:

[
  {"code": "ALPHA", "value": 12.0},
  {"code": "CHARLIE", "value": 10.5},
  ...
  {"code": "FOX", "value": 3.5},
  ...
  {"code": "ZOMBIE", "value": 7.0}
]

I want to ensure that somewhere in the returned array, there is an object with "code": "FOX". The position of this object in the array is not fixed — it just needs to be present.

If I define the contract like this:

DslPart dslPart = PactDslJsonArray.arrayMinLike(1)
    .stringType("code", "AnyCode")
    .decimalType("value", new BigDecimal("10.00"))
    .closeObject();

Then the provider test passes regardless of what code values are returned — it doesn't guarantee that "FOX" is present.

If I define it like this:

DslPart dslPart = PactDslJsonArray.arrayMinLike(1)
    .stringMatcher("code", "FOX")
    .decimalType("value", new BigDecimal("10.00"))
    .closeObject();

Then the provider test fails unless every item in the array has "code": "FOX", which is not what I want either.

Eventually, I found that I can achieve the desired check using the following DSL:

DslPart dslPart = PactDslJsonArray.newUnorderedMinArray(1)
    .object()
    .stringMatcher("code", "FOX")
    .decimalType("value", new BigDecimal("10.00"))
    .closeObject();

This seems to work as expected on the provider side — the test passes only if at least one item matches "code": "FOX".

However, the generated contract contains this matcher metadata:

"$": {
  "combine": "AND",
  "matchers": [
    {
      "match": "ignore-order",
      "min": 1
    }
  ]
}

And this causes pact-stub-server to fail with the following error:

ERROR main pact_stub_server: - Failed to load pact file: Failed to parse Pact JSON - /app/pacts/contract-service.json
ERROR main pact_stub_server: - Failed to load pact file: Could not parse matcher JSON Object {"match": String("ignore-order"), "min": Number(1)} - /app/pacts/contract-service.json

Is there a way to define a contract that ensures the array includes at least one object matching a specific pattern (e.g., "code": "FOX"), but still keeps the contract compatible with pact-stub-server?

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionIndicates that an issue, pull request, or discussion needs more information

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions