Below is an example of a PACT Consumer tests with example in Groovy.

  1. Import the library
Ensure that we downloaded the PACT consumer library from Maven repository import them in your consumer test file. We also need to include REST Client to make API calls and JUnit for assertion.
import au.com.dius.pact.consumer.PactVerified$
import au.com.dius.pact.consumer.groovy.PactBuilder
import groovyx.net.http.RESTClient
import org.junit.Test

    2. Define the consumer service that will consume the API provider


Example below is a consumer test class that defines a consumer service “Consumer” that is requesting data from API provider “Provider”. The API request is a GET method with parameter “q” with some value. Upon success, it returns a response code of 200 with Content-Type of “application/json;charset=UTF-8”. 

class ConsumerTests {

    @Test
    void “Consumer test for Consumer and Provider”() {
        def consumer_service = new PactBuilder()
        consumer_service {
            serviceConsumer “Consumer”
            hasPactWith “Provider”
            port 1237

            given(‘Scenario of Consumer is retrieving data from Provider’)
            uponReceiving(‘a retrieve a data request’)
            withAttributes(method: ‘get’, path: ‘/consumer/search’, query: [q: ‘refKey:4e6b75c2-b527-4af0-a098-b2ba81706bdc’], headers: [‘Accept’: ‘text/plain’, ‘Content-Type’: ‘application/json’])
            willRespondWith(
                    status: 200,
                    headers: [‘Content-Type’: ‘application/json; charset=UTF-8’]
            )

            withBody {

 }

3. Define the response body

There are 2 ways to define the response body.

(a) Response body with exact or fixed data.

Use this method if you need to test that the data returned by the API is exactly the same as what you defined in the consumer test.

For example:

  withBody{
                “Id” (“87992”)
                “Seller” (“Michael”)
                “CompanyName” (“ABC123”)
}

The example above will generate a PACT JSON file that looks like:

  “response” : {
      “status” : 200,
      “headers” : {
        “Content-Type” : “application/json;charset=utf-8”
      },
      “body” : {
        “Id” : “87992”,
        “Seller” : “Michael”,
        “CompanyName” : “ABC123”
      }
    }

So the PACT provider test will check for a response with body with exactly the same structure and data as the PACT JSON file.

(b) Response body with flexible data

Use this method if you only want to test that the contract or structure of the API remains the same. This is useful in the scenario when data changes frequently and the effort of test data maintenance is high.

For example:

  withBody{
                “Id” regexp(~/w.+/,”87992″)
                “SellerGuid” regexp(~/w.+/,”Michael”)
                “CompanyName” regexp(~/w.+/, “ABC123”)
}

The example above will generate PACT JSON file that looks like:

 “response” : {
      “status” : 200,
      “headers” : {
        “Content-Type” : “application/json;charset=utf-8”
      },
      “body” : {
        “Id” : “87992”,
        “SellerGuid” : “Michael”,
        “CompanyName” : “ABC123”
      },
      “matchingRules” : {
        “$.body.Id” : {
          “regex” : “\w.+”
        },
        “$.body.SellerGuid” : {
          “regex” : “\w.+”
        },
        “$.body.CompanyName” : {
          “regex” : “\w.+”
        }
      }

Instead of passing the exact data to match, we pass in a regular expression instead. Therefore, a set of matching rules will be generated in the PACT JSON file. PACT Provider test will look at the matching rules and ignore the data. So, if Company Name is changed from “ABC123” to “ABC678”, the test will still pass as the data still matches the regular expression defined.

This is a good example of a consumer with body that uses flexible matching of many different data types such as string, integer, IP, time stamp, etc.

Another key features of the flexible matching is the flexible array matching.

For example:

    hits minLike(1) {
                        _index(~/w.+/, “12345”)
                        _type(~/w.+/, “Dog”)
                        _id(~/d+/, “263287”)
                        _score real()

The above is useful if the JSON output that you want to test has array structures and the number of arrays in the structure changes.

More information can be found here

(4) Generate the PACT file

The last part of the consumer test is basically generating the PACT JSON output.


For example:

   def result = consumer_service.run() {
                def client = new RESTClient(‘http://localhost:1237/’)

                def response = client.get(path: ‘/consumer/search’, query: [q: ‘refKey:4e6b75c2-b527-4af0-a098-b2ba81706bdc’], headers: [‘Accept’: ‘text/plain’, ‘Content-Type’: ‘application/json’])

                assert response.status == 200
   
                consumer_service.buildInteractions()
            }


If everything is defined correctly, a JSON output will be generated in the file structure under the “target” directory.

The JSON output is contract of the API that you have defined in the consumer test, which is the API that the consumer consumes.