
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Implementation of the consumer driven contract library Pact for Javascript.
From the Pact website:
The Pact family of frameworks provide support for Consumer Driven Contracts testing.
A Contract is a collection of agreements between a client (Consumer) and an API (Provider) that describes the interactions that can take place between them.
Consumer Driven Contracts is a pattern that drives the development of the Provider from its Consumers point of view.
Pact is a testing tool that guarantees those Contracts are satisfied.
Read Getting started with Pact for more information on how to get going.
NOTE: This project supersedes Pact Consumer JS DSL.
It's easy, simply run the below:
npm install --save-dev pact
Check out Pact JS Mocha.
To use the library on your tests, add the pact dependency:
let Pact = require('pact')
The Pact
interface provides the following high-level APIs, they are listed in the order in which they typically get called in the lifecycle of testing a consumer:
API | Options | Returns | Description |
---|---|---|---|
pact(options) | See Pact Node documentation for options | Object | Creates a Mock Server test double of your Provider API. If you need multiple Providers for a scenario, you can create as many as these as you need. |
setup() | n/a | Promise | Start the Mock Server |
addInteraction() | Object | Promise | Register an expectation on the Mock Server, which must be called by your test case(s). You can add multiple interactions per server. These will be validated and written to a pact if successful. |
verify() | n/a | Promise | Verifies that all interactions specified |
finalize() | n/a | Promise | Records the interactions registered to the Mock Server into the pact file and shuts it down. |
removeInteractions | n/a | Promise | In some cases you might want to clear out the expectations of the Mock Service, call this to clear out any expectations for the next test run. NOTE: verify() will implicitly call this. |
The first step is to create a test for your API Consumer. The example below uses Mocha, and demonstrates the basic approach:
Check out the examples
folder for examples with Karma Jasmine, Mocha and Jest. The example below is taken from the integration spec.
let path = require('path')
let chai = require('chai')
let pact = require('pact')
let request = require ('superagent')
let chaiAsPromised = require('chai-as-promised')
let expect = chai.expect
chai.use(chaiAsPromised);
describe('Pact', () => {
// (1) Create the Pact object to represent your provider
const provider = pact({
consumer: 'TodoApp',
provider: 'TodoService',,
port: MOCK_SERVER_PORT,
log: path.resolve(process.cwd(), 'logs', 'pact.log'),
dir: path.resolve(process.cwd(), 'pacts'),
logLevel: 'INFO',
spec: 2
});
// this is the response you expect from your Provider
const EXPECTED_BODY = [{
id: 1,
name: 'Project 1',
due: '2016-02-11T09:46:56.023Z',
tasks: [
{id: 1, name: 'Do the laundry', 'done': true},
{id: 2, name: 'Do the dishes', 'done': false},
{id: 3, name: 'Do the backyard', 'done': false},
{id: 4, name: 'Do nothing', 'done': false}
]
}]
context('when there are a list of projects', () => {
describe('and there is a valid user session', () => {
before((done) => {
// (2) Start the mock server
provider.setup()
// (3) add interactions to the Mock Server, as many as required
.then(() => {
provider.addInteraction({
state: 'i have a list of projects',
uponReceiving: 'a request for projects',
withRequest: {
method: 'GET',
path: '/projects',
headers: { 'Accept': 'application/json' }
},
willRespondWith: {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: EXPECTED_BODY
}
})
})
.then(() => done())
})
// (4) write your test(s)
it('should generate a list of TODOs for the main screen', (done) => {
const todoApp = new TodoApp();
const projects = todoApp.getProjects() // <- this method would make the remote http call
expect(projects).to.eventually.be.a('array')
expect(projects).to.eventually.have.deep.property('projects[0].id', 1).notify(done)
})
// (5) validate the interactions occurred, this will throw an error if it fails telling you what went wrong
it('creates a contract between the TodoApp and TodoService', () => {
return pact.verify()
})
})
});
// (6) write the pact file for this consumer-provider pair,
// and shutdown the associated mock server.
// You should do this only _once_ per Provider you are testing.
after(() => {
provider.finalize()
});
})
Once you have created Pacts for your Consumer, you need to validate those Pacts against your Provider. The Verifier object provides the following API for you to do so:
API | Options | Returns | Description |
---|---|---|---|
verifyProvider() | n/a | Promise | Start the Mock Server |
const verifier = require('pact').Verifier;
let opts = {
providerBaseUrl: <String>, // Running API provider host endpoint. Required.
pactUrls: <Array>, // Array of local Pact file paths or Pact Broker URLs (http based). Required.
providerStatesUrl: <String>, // URL to fetch the provider states for the given provider API. Optional.
providerStatesSetupUrl <String>, // URL to send PUT requests to setup a given provider state. Optional.
pactBrokerUsername: <String>, // Username for Pact Broker basic authentication. Optional
pactBrokerPassword: <String>, // Password for Pact Broker basic authentication. Optional
};
verifier.verifyProvider(opts)).then(function () {
// do something
});
That's it! Read more about Verifying Pacts.
Sharing is caring - to simplify sharing Pacts between Consumers and Providers, checkout sharing pacts using the Pact Broker.
let pact = require('@pact-foundation/pact-node');
let opts = {
pactUrls: <Array>, // Array of local Pact files or directories containing them. Required.
pactBroker: <String>, // URL to fetch the provider states for the given provider API. Optional.
pactBrokerUsername: <String>, // Username for Pact Broker basic authentication. Optional
pactBrokerPassword: <String>, // Password for Pact Broker basic authentication. Optional
consumerVersion: <String> // A string containing a semver-style version e.g. 1.0.0. Required.
};
pact.publishPacts(opts)).then(function () {
// do something
});
Jest uses JSDOM under the hood which may cause issues with libraries making HTTP request. See this issue for background, and the Jest example for a working solution.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)If you would like to implement Pact
in another language, please check out the Pact specification and have a chat to one of us on the pact-dev Google group.
The vision is to have a compatible Pact
implementation in all the commonly used languages, your help would be greatly appreciated!
2.0.0 (2017-02-22)
<a name="1.0.0"></a>
FAQs
Pact for all things Javascript
The npm package pact receives a total of 1,160 weekly downloads. As such, pact popularity was classified as popular.
We found that pact demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 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
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.