pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 479 forks source link

Unable to specify body matchers for x-www-form-urlencoded body like JSON body #1277

Open mikahjc opened 3 years ago

mikahjc commented 3 years ago

We are trying to implement a pact where the request body is a URL-encoded form, but our client doesn't guarantee the order of parameters because they are in a set. This causes the stub server to report a mismatch because the hard-coded string that we give it for the body doesn't match. For example, a body of id=1&value=1&value=2&value=3 may be sent by the consumer as id=1&value=3&value=1&value=2.

We did try using PactDslRootValue.stringMatcher() with a regex like /^id=\d+&(value=\d+&?)+/, but that didn't work as we anticipated. We got a BodyMismatch exception:

BodyMismatch(expected=1, actual=1, mismatch=Expected '1' to match '^id=\d+&(value=\d+&?)+', path=$.id.0, diff=null)

...and the value field yields similar errors:

BodyMismatch(expected=1, actual=8, mismatch=Expected '8' to match '^userId=\d+&(fid=\d+&?)+', path=$.value.0, diff=null)

(yes, I know the mismatch message is using the actual value, but the rest of the mismatch exceptions were as expected)

I had thought that there may be a way to specify the matchers manually, but it feels like maybe there should be another LambdaDSL or something similar to specify the schema of a URL-encoded form. It seems that it's somewhat aware that the different properties/arrays exist in the body, it's just a matter of passing in the right spec to the .body() method.

uglyog commented 3 years ago

I've added a builder to construct the body. See https://github.com/pact-foundation/pact-jvm/blob/master/consumer/junit5/src/test/java/au/com/dius/pact/consumer/junit5/UrlEncocdedFormPostTest.java#L38 for an example.

uglyog commented 3 years ago

4.1.13 released