
Security News
How Enterprise Security Is Adapting to AI-Accelerated Threats
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.
Jest-Pact RoadmapJestProvidedPactFnV4JestProvidedPactFn default to JestProvidedPactFnV4JestProvidedPactFn to JestProvidedPactFnV2npm install --save-dev jest-pact
yarn add jest-pact --dev
If you have more than one file with pact tests for the same consumer/provider
pair, you will also need to add --runInBand to your jest or react-scripts test command in your package.json. This avoids race conditions with the mock
server writing to the pact file.
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),
/* other endpoints here */
});
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', () => {
// Here we set up the interaction that the Pact
// mock provider will expect.
//
// jest-pact takes care of validating and tearing
// down the provider for you.
beforeEach(() => // note the implicit return.
// addInteraction returns a promise.
// If you don't want to implicitly return,
// you will need to `await` the result
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',
},
})
);
// You also test that the API returns the correct
// response to the data layer.
//
// Although Pact will ensure that the provider
// returned the expected object, you need to test that
// your code receives the right object.
//
// This is often the same as the object that was
// in the network response, but (as illustrated
// here) not always.
it('returns server health', () => // implicit return again
client.getHealth().then(health => {
expect(health).toEqual('up');
}));
});
});
We also include a wrapper for Pact-JS V3.
Note: The API is NOT finalised. Feedback welcome
If you have thoughts or feedback about the DSL, please let us know via slack or open issue.
Currently, only a default for the pact directory is provided by the jest-pact wrapper jest-pact/dist/v3.
import { pactWith } from 'jest-pact/dist/v3';
import { MatchersV3 } from '@pact-foundation/pact';
import api from 'yourCode';
pactWith({ consumer: 'MyConsumer', provider: 'MyProvider' }, (interaction) => {
interaction('A request for API health', ({ provider, execute }) => {
beforeEach(() =>
provider
.given('Server is healthy')
.uponReceiving('A request for API health')
.withRequest({
method: 'GET',
path: '/health',
})
.willRespondWith({
status: 200,
body: {
status: MatchersV3.like('up'),
},
})
);
execute('some api call', (mockserver) =>
api(mockserver.url)
.health()
.then((health) => {
expect(health).toEqual('up');
})
);
});
});
You can make your tests easier to read by extracting your request and responses:
/* pact.fixtures.js */
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.getHealth().then(health => {
expect(health).toEqual('up');
}));
});
addInteraction in beforeEach.
You can return the promise, or use async/await. If you forget this,
your interaction may not be set up before the test runs.it. You can
return the promise, or use async/await. If you forget this, your
test may pass before the expect assertion runs, causing a potentially
false success.--runInBand. If you have multiple test files that
write to the same contract, you will need this to avoid intermittent failures
when writing the contract file.pactWith,
otherwise the logs will get overwritten when other specs start. If you provide an
explicit port, then the default mockserver log filename includes the port number.Jest-Pact has two primary functions:
pactWith(JestPactOptions, (providerMock) => { /* tests go here */ }): a wrapper that sets up a pact mock provider, applies sensible default options, and applies the setup and verification hooks so you don't have tomessagePactWith(JestMessageConsumerOptions, (messagePact) => { /* tests go here */ }): a wrapper that sets up a message pact instance and applies sensible default optionsAdditionally, pactWith.only / fpactWith, pactWith.skip / xpactWith, messagePactWith.only / fmessagePactWith and messagePactWith.skip / xmessagePactWith behave as you would expect from Jest.
There are two types exported (depending on whether you are using the V2 or V3 Pact interface):
JestProvidedPactFn: This is the type of the second argument to pactWith, ie: (provider: PactV2) => voidJestPactOptions: An extended version of PactV2Options that has some additional convenience options (see below).JestProvidedPactFnV3: This is the type of the second argument to pactWith, ie: (provider: PactV3) => voidJestPactOptionsV3: An extended version of PactV3Options that has some additional convenience options (see below).You can use all the usual PactV2Options/PactV3Options from pact-js, plus a timeout for
telling jest to wait a bit longer for pact to start and run.
pactWith(JestPactOptions, (provider) => {
// regular http pact tests go here
});
messagePactWith(JestMessageConsumerOptions, (messagePact) => {
// regular message pact tests go here
});
interface ExtraOptions {
timeout?: number; // Timeout for pact service start/teardown, expressed in milliseconds
// Default is 30000 milliseconds (30 seconds).
logDir?: string; // path for the log file
logFileName?: string; // filename for the log file
}
type JestPactOptions = PactV2Options & ExtraOptions;
type JestMessageConsumerOptions = MessageConsumerOptions & ExtraOptions;
Jest-Pact sets some helpful default PactV2Options/PactV3Options for you. You can override any of these by explicitly setting corresponding option. Here are the defaults:
log is set so that log files are written to /pact/logs, and named <consumer>-<provider>-mockserver-interaction.log. If you provided an explicit port, then the log file name is <consumer>-<provider>-mockserver-interaction-port-<portNumber>.logdir is set so that pact files are written to /pact/pactslogLevel is set to warntimeout is 30,000 milliseconds (30 seconds)pactfileWriteMode is set to "update"Most of the time you won't need to change these.
A common use case for log is to change only the filename or the path for
logging. To help with this, Jest-Pact provides convenience options logDir
and logFileName. These allow you to set the path or the filename
independently. In case you're wondering, if you specify log, logDir and
logFileName, the convenience options are ignored and log takes
precedence.
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 around 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
jest-pactSee Jest-Pact-Typescript which showcases a full consumer workflow written in Typescript with Jest, using this adaptor
git@github.com:YOU54F/jest-pact-typescript.gityarn installyarn run pact-testGenerated pacts will be output in pact/pacts
Log files will be output in pact/logs
0.13.0 (2025-10-07)
FAQs
a pact adaptor for jest
The npm package jest-pact receives a total of 20,245 weekly downloads. As such, jest-pact popularity was classified as popular.
We found that jest-pact demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.