Skip to content

teamradhq/learning-jest-matchers

Repository files navigation

Learning Jest Matchers

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

Information

Symmetric Matcher

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);

Asymmetric Matcher

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)
);

Type Declarations

Depending on the type of matcher, we will need to extend a combination of the following types:

  • jest.Expect
  • jest.Matchers
  • jest.ExpectExtendMap

Matchers

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,
});

References

About

Examples of custom matcher definitions that can be used to make assertions within the Jest testing framework

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published