Pattern Matching with Pact

Mar 25, 2015   #java  #pact  #microservices  #testing 

It seems the internet is missing an example of how to match the JSON body against a regex when testing your microservices with Pact-JVM. So I made one myself.

Our consumer contract expects the provider to return three fields in the response body: id, description and random.

While id and description can be specified exactly by the consumer, the random-field cannot. We just know the provider will return a random 6-digit number as a string. So we create a regular expression for that inside a PactDslJsonBody.

@Override protected PactFragment createFragment(final ConsumerPactBuilder.PactDslWithProvider builder) { Map headers = new HashMap<>(); headers.put("Content-Type", "application/json;charset=UTF-8"); DslPart body = new PactDslJsonBody() .numberValue("id", 1) .stringValue("description", "This is the description for product 1") .stringMatcher("random", "[0-9]{6}"); return builder .uponReceiving("a request for product details") .path("/productdetails/1") .method("GET") .willRespondWith() .headers(headers) .status(200) .body(body) .toFragment(); }

When the consumer test is run, this Pactfile is created:

{ "provider" : { "name" : "Product_Details_Service" }, "consumer" : { "name" : "Product_Service" }, "interactions" : [ { "description" : "a request for product details", "request" : { "method" : "GET", "path" : "/productdetails/1" }, "response" : { "status" : 200, "headers" : { "Content-Type" : "application/json;charset=UTF-8" }, "body" : { "id" : 1, "description" : "This is the description for product 1", "random" : "413558" }, "responseMatchingRules" : { "$.body.random" : { "regex" : "[0-9]{6}" } } } } ], "metadata" : { "pact-specification" : { "version" : "2.0.0" }, "pact-jvm" : { "version" : "2.1.7" } } }

Note that Pact magically replaced the regex with a matching string inside the body definition. This makes sure the provider-stub returns something useful for the consumer when the consumer tests are run. But when the pact is verified against the provider, Pact will use the regular expression inside responseMatchingRules instead of just matching against the final string for each field in body that has a corresponding regex.