This collection contains a number of custom Jest matchers. It can be used as a guide to learn how to write and implement custom matchers.
Setting up and running tests:
nvm use 18
npm install
npm run test
A symmetric matcher asserts something in its entirety.
This can be considered a strict equality matcher:
expect(actual).toStrictEqual(expected);
expect(actual).toBeTruthy();
expect(actual).toBeCalledTimes(n);
An asymmetric matcher asserts something partially.
This can be considered a loose equality matcher:
expect(actual).toEqual(expect.any(String));
expect(actual).toEqual(expect.arrayContaining([1, 2, 3]));
Instead of being called directly, asymmetric matchers are passed as arguments to a symmetric matcher:
expect(actual).toSymmetricMatch(
expect.toAsymmetricMatch(expected)
);
Depending on the type of matcher, we will need to extend a combination of the following types:
jest.Expect
jest.Matchers
jest.ExpectExtendMap
A matcher accepts the actual value as its first argument, and any number of additional arguments for comparison. It should return an object containing the following properties:
message
: A function that returns a string to be displayed when the matcher fails.pass
: A boolean indicating whether the matcher passed or failed.
function toMatch(actual: unknown, expected: unknown): jest.CustomMatcherResult {
const pass = actual === expected;
const message = () => `expected ${actual} to match ${expected}`;
return {message, pass};
}
We should still return a message
when a test passes so that inverse matchers can display a useful message:
function toMatch(actual: unknown, expected: unknown): jest.CustomMatcherResult {
const pass = actual === expected;
const message = () => `expected ${actual} to match ${expected}`;
return {
pass,
message: pass
? () => `expected ${actual} to match ${expected}`
: () => `expected ${actual} not to match ${expected}`
};
}
In order to use a custom matcher, we should add it to the expect
object using expect.extend
:
// jest.setup.ts
import {
toMatch,
toResolve,
toReject,
} from './matchers';
expect.extend({
toMatch,
toResolve,
toReject,
});