Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Basically the same as jest-pact
, but for mocha
# npm
npm install --save-dev mocha-pact
# yarn
yarn add mocha-pact --dev
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 'mocha-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.
//
// mocha-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 implict 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 recieves 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');
}));
});
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 'mocha-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');
}));
});
Forgetting to wait for the promise from 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.
Forgetting to wait for the promise of your API call in 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.
It's a good idea to specify a different log file for each invocation of 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.
If you are using eslint-plugin-mocha
with the recommended settings, you will need to disable the rule mocha/no-setup-in-describe
:
// .eslintrc.json
"rules": {
"mocha/no-setup-in-describe": "off",
...
}
This is because mocha-pact dynamically generates the test setup for you.
Disabling this rule is the approach recommended in the
eslint-plugin-mocha
documentation
for when you have dynamically generated tests.
Mocha-Pact has two primary functions:
pactWith(MochaPactOptions, (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(MochaMessageConsumerOptions, (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 Mocha.
There are two types exported:
MochaProvidedPactFn
: This is the type of the second argument to pactWith
, ie: (provider: Pact) => void
MochaPactOptions
: An extended version of PactOptions
that has some additional convienience options (see below).MochaMessageConsumerOptions
: An extended version of MessagePactOptions
that has some additional convienience options (see below).You can use all the usual PactOptions
from pact-js, plus a timeout for
telling mocha to wait a bit longer for pact to start and run.
pactWith(MochaPactOptions, (provider) => {
// regular http pact tests go here
});
messagePactWith(MochaMessageConsumerOptions, (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 MochaPactOptions = PactOptions & ExtraOptions;
type MochaMessageConsumerOptions = MessageConsumerOptions & ExtraOptions;
Mocha-Pact sets some helpful default PactOptions 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>.log
dir
is set so that pact files are written to /pact/pacts
logLevel
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, Mocha-Pact provides convienience 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 convienience options are ignored and log
takes
precidence.
FAQs
a pact adaptor for mocha
The npm package mocha-pact receives a total of 26 weekly downloads. As such, mocha-pact popularity was classified as not popular.
We found that mocha-pact demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 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.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.