Jest-Pact
Jest Adaptor to help write Pact files with ease
Features
Jest-Pact
Roadmap
Adapter Installation
npm i jest-pact --save-dev
OR
yarn add jest-pact --dev
Usage
pactWith({ consumer: 'MyConsumer', provider: 'MyProvider' }, provider => {
}
Example
Say that your API layer looks something like this:
import axios from 'axios';
const defaultBaseUrl = "http://your-api.example.com"
export const api = (baseUrl = defaultBaseUrl) => ({
getHealth: () => axios.get(`${baseUrl}/health`)
.then(response => response.data.status)
})
Then your test might look like:
import { pactWith } from 'jest-pact';
import { Matchers } from '@pact-foundation/pact';
import api from 'yourCode';
pactWith({ consumer: 'MyConsumer', provider: 'MyProvider' }, provider => {
let client;
beforeEach(() => {
client = api(provider.mockService.baseUrl)
});
describe('health endpoint', () => {
beforeEach(() =>
provider.addInteraction({
state: "Server is healthy",
uponReceiving: 'A request for API health',
willRespondWith: {
status: 200,
body: {
status: Matchers.like('up'),
},
},
withRequest: {
method: 'GET',
path: '/health',
},
})
);
it('returns server health', () =>
client.health().then(health => {
expect(health).toEqual('up');
}));
});
You can make your tests easier to read by extracting your request and responses:
import { Matchers } from '@pact-foundation/pact';
export const healthRequest = {
uponReceiving: 'A request for API health',
withRequest: {
method: 'GET',
path: '/health',
},
};
export const healthyResponse = {
status: 200,
body: {
status: Matchers.like('up'),
},
}
import { pactWith } from 'jest-pact';
import { healthRequest, healthyResponse } from "./pact.fixtures";
import api from 'yourCode';
pactWith({ consumer: 'MyConsumer', provider: 'MyProvider' }, provider => {
let client;
beforeEach(() => {
client = api(provider.mockService.baseUrl)
});
describe('health endpoint', () => {
beforeEach(() =>
provider.addInteraction({
state: "Server is healthy",
...healthRequest,
willRespondWith: healthyResponse
})
);
it('returns server health', () =>
client.health().then(health => {
expect(health).toEqual('up');
}));
});
Configuration
pactWith(PactOptions, provider => {
}
interface PactOptions {
provider: string;
consumer: string;
port?: number;
pactfileWriteMode?: PactFileWriteMode;
dir? string
}
type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
type PactFileWriteMode = "overwrite" | "update" | "merge";
Defaults
- Log files are written to /pact/logs
- Pact files are written to /pact/pacts
Jest Watch Mode
By default Jest will watch all your files for changes, which means it will run in an infinite loop as your pact tests will generate json pact files and log files.
You can get round this by using the following watchPathIgnorePatterns: ["pact/logs/*","pact/pacts/*"]
in your jest.config.js
Example
module.exports = {
testMatch: ["**/*.test.(ts|js)", "**/*.it.(ts|js)", "**/*.pacttest.(ts|js)"],
watchPathIgnorePatterns: ["pact/logs/*", "pact/pacts/*"]
};
You can now run your tests with jest --watch
and when you change a pact file, or your source code, your pact tests will run
Examples of usage of jest-pact
See Jest-Pact-Typescript which showcases a full consumer workflow written in Typescript with Jest, using this adaptor
Examples Installation
- clone repository
git@github.com:YOU54F/jest-pact-typescript.git
- Run
yarn install
- Run
yarn run pact-test
Generated pacts will be output in pact/pacts
Log files will be output in pact/logs
Credits