Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pact matcher for different number of elements in array #1318

Closed
iankurrathi opened this issue Mar 3, 2021 · 6 comments
Closed

pact matcher for different number of elements in array #1318

iankurrathi opened this issue Mar 3, 2021 · 6 comments
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@iankurrathi
Copy link
Contributor

iankurrathi commented Mar 3, 2021

Hi,
I have an endpoint which returns following format of response:

{
    "output": [
        "a",
        "b",
        "c"
    ]
}

This service can return any number of elements in array.
I was using 4.1.17 version of pact consumer and using array for matcher but it seems that matcher requires exact number of elements to be specified in pact.

My old code:

    @Pact(consumer = "test")
    private RequestResponsePact method(PactDslWithProvider builder) {
        return builder
                .given("test")
                .uponReceiving("test")
                .path("/api")
                .method(HttpGet.METHOD_NAME)
                .willRespondWith()
                .status(HttpStatus.SC_OK)
                .body(newJsonBody(o -> {
                    o.array("output", a -> {
                       a.stringType("a");
                    });
                }).build())
                .toPact();
    }

That's the matcher in json file:

"matchingRules": {
          "body": {
            "$.output[0]": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }

This gives me following error:

Verifying a pact between test
  [Using File pacts/test-test.json]
  Given test
  test
    returns a response which
      has status code 200 (OK)
      has a matching body (FAILED)

Failures:

1) Verifying a pact between test and test - test has a matching body

    1.1) body: $.output Expected a List with 1 elements but received 3 elements

        [
        -  "a"
        +  "a",
        +  "b",
        +  "c"
        ]

As suggested to me in my stackoverflow question that I should use arrayContaining() method which supports varying list of elements in array.
I updated my code to following after updating pact consumer version to 4.2.0:

@Pact(consumer = "test")
    private RequestResponsePact method(PactDslWithProvider builder) {
        return builder
                .given("test")
                .uponReceiving("test")
                .path("/api")
                .method(HttpGet.METHOD_NAME)
                .willRespondWith()
                .status(HttpStatus.SC_OK)
                .body(newJsonBody(o -> {
                    o.arrayContaining("output", a -> {
                       a.stringType("a");
                    });
                }).build())
                .toPact();
    }

It generates following matcher in json file:

"matchingRules": {
          "body": {
            "$.output": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "arrayContains",
                  "variants": [
                    {
                      "generators": {

                      },
                      "index": 0,
                      "rules": {
                        "[0]": {
                          "combine": "AND",
                          "matchers": [
                            {
                              "match": "type"
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              ]
            }
          }

However it gives me following error now:

Verifying a pact between test
  [Using File pacts/test-test.json]
  Given test
  test
      Request Failed - Path expression "[0]" does not start with a root marker "$"

Failures:

1) Verifying a pact between test and test - test

    1.1)       Path expression "[0]" does not start with a root marker "$"

Any help on this will be appreciated.
Thanks.

@uglyog
Copy link
Member

uglyog commented Mar 6, 2021

What are you using to verify the pact with? That error means that the pact file is being verified as a V2 format, but the array contains matcher only works with V3 and V4 formatted pacts.

@uglyog uglyog added the bug Indicates an unexpected problem or unintended behavior label Mar 6, 2021
@uglyog
Copy link
Member

uglyog commented Mar 6, 2021

Looks like there is an issue with the array contains matcher with simple values in the array.

@iankurrathi
Copy link
Contributor Author

What are you using to verify the pact with? That error means that the pact file is being verified as a V2 format, but the array contains matcher only works with V3 and V4 formatted pacts.

Thanks for looking into. I am using 4.2.0 for both consumer and producer which I believe follows V4 specification.

@iankurrathi
Copy link
Contributor Author

I see that you have put in a fix for this issue, can you please let me know which release version will have this fix? Thanks.

@uglyog
Copy link
Member

uglyog commented Mar 13, 2021

4.2.2 released

@iankurrathi
Copy link
Contributor Author

array matching works in 4.2.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

2 participants