Transcripted Summary

In this chapter we will create our first contract test, then verify the logs as well as the contracts themselves.

Creating Consumer Tests

First, navigate to the consumer folder and create the file ClientsConsumer.spec.js within it.


"use strict"

const { Matchers } = require("@pact-foundation/pact")
const { getClients, postClient } = require("../../../src/consumer")

describe("Clients Service", () => {
   const GET_EXPECTED_BODY = [{
   	"firstName": "Lisa",
   	"lastName": "Simpson",
   	"age": 8,
   	"id": 1
   },
   {
   	"firstName": "Wonder",
   	"lastName": "Woman",
   	"age": 30,
   	"id": 2
   },
   {
   	"firstName": "Homer",
   	"lastName": "Simpson",
   	"age": 39,
   	"id": 3
   }]

   afterEach(() => provider.verify())

   describe("GET Clients", () => {
   	beforeEach(() => {
       	const interaction = {
           	state: "i have a list of clients",
           	uponReceiving: "a request for all clients",
           	withRequest: {
               	method: "GET",
               	path: "/clients",
               	headers: {
                   	Accept: "application/json, text/plain, */*",
               	},
           	},
           	willRespondWith: {
               	status: 200,
               	headers: {
                   	"Content-Type": "application/json; charset=utf-8",
               	},
               	body: GET_EXPECTED_BODY,
           	},
       	}
       	return provider.addInteraction(interaction)
   	})

   	test("returns correct body, header and statusCode", async() => {
       	const response = await getClients()
       	expect(response.headers['content-type']).toBe("application/json; charset=utf-8")
       	expect(response.data).toEqual(GET_EXPECTED_BODY)
       	expect(response.status).toEqual(200)
   	})
   })
})

NOTE

use strict prevents the use of undeclared variables.


Then we require the libraries so we will need to define matchers to create assertions.


const { Matchers } = require("@pact-foundation/pact")

Next, import the consumer functions that will be used for test creation. For this example we will use the getClients and postClient endpoints. Two scenarios will be created, one to get clients and another to post the client.


const { getClients, postClient } = require("../../../src/consumer")

Creating Contracts

The describe() call will contain the getClients and postClient tests. For now, we are going to create just the getClients test. First, create the constant GET_EXPECTED_BODY which contains the body we expect to receive after we send the request. In this example the expected body after sending getClients is a first name, last name, age, and id.

This interaction consists of the request that will be sent to the mock provider. Pact will receive these requests and validate them according to the expectations defined in the contract. This contract can then be used to verify that everything is okay on the provider side as well. Now update the body:


describe("Clients Service", () => {
   const GET_EXPECTED_BODY = [{
   	"firstName": "Lisa",
   	"lastName": "Simpson",
   	"age": 8,
   	"id": 1
   },
   {
   	"firstName": "Wonder",
   	"lastName": "Woman",
   	"age": 30,
   	"id": 2
   },
   {
   	"firstName": "Homer",
   	"lastName": "Simpson",
   	"age": 39,
   	"id": 3
   }]

The following line ensures that any errors occurring from interactions registered with Pact will be logged and the test will fail. Basically this is where Pact verifies the interactions we are sending.


afterEach(() => provider.verify())

Now we are going to create our getClients test. beforeEach is where we set everything required to initiate the interaction.



state is simply the state of the scenario before running the test. uponReceiving is a description of the request to get our clients. withRequests is the request parameters. method specifies the action, e.g. a POST, GET or PUT. path in this case is “/clients”. In this scenario testing getClients we don't need to send the body, only the method, path and headers.



willRespondWith specifies what we expect to receive back from the server. We expect to receive a status code of 200 and the specified headers. The expected body will also be set using the previously defined constant GET_EXPECTED_BODY.

Now we need to add this interaction after creating the scenario:


return provider.addInteraction(interaction)

This call registers expectations, requests, and essentially everything that needs to be verified for this scenario.


Creating Assertions

Now that the contract is created we will create the test and test assertions for this contract.



In the above code, once the getClients() response is received, the same function we are using on the consumer side will make a request to the real provider. We receive the response and then perform assertions based on expectations for the response header and body. We are going to check that the response data is equal to the body that we expect to receive from the source. We also expect to receive a status code equal to 200.

Note that we are not using matchers in this scenario. Everything that we expect on the body needs to be exactly what we are sending in willRespondWith. In the real world you may choose not to choose this approach because what really matters is the field values and types you are receiving back from the source.


Running the Test

Now we can run our tests and create our contract. Go to your terminal and run the following command:



npm run test:consumer




As we can see the scenario passes and we got the correct body, header and status code back. Now we can check on the contract frontend-clientservice.json that was generated inside of the pacts folder. Check the consumer, provider, and the request that we sent and received back:


{
 "consumer": {
   "name": "Frontend"
 },
 "provider": {
   "name": "ClientsService"
 },
 "interactions": [
   {
        "description": "a request for all clients",
        "providerState": "i have a list of clients",
        "request": {
            "method": "GET",
            "path": "/clients",
            "headers": {
                "Accept": "application/json, text/plain, */*"
            }
 	    },
        "response": {
            "status": 200,
            "headers": {
                "Content-Type": "application/json; charset=utf-8"
            },
            "body": [
                {
                "firstName": "Lisa",
                "lastName": "Simpson",
                "age": 8,
                "id": 1
                },
                {
                "firstName": "Wonder",
                "lastName": "Woman",
                "age": 30,
                "id": 2
                },
                {
                "firstName": "Homer",
                "lastName": "Simpson",
                "age": 39,
                "id": 3
                }
            ]
            }
        }
        ],
 "metadata": {
   "pactSpecification": {
 	"version": "2.0.0"
   }
 }
}

Finally, inspect the logs. We can see the request that was sent as well as the response received.



Conclusion

In the first video of this chapter we successfully generated our first contract and our first consumer tests. In the next video we will learn how to run the provider verifier.



Resources



Quiz

The quiz for this chapter can be found in section 3.2

© 2021 Applitools. All rights reserved. Terms and Conditions Privacy Policy GDPR