The Jest Functions You’ll Actually Use

A practical reference to the Jest functions that come up in almost every test suite — with a short example for each. New to Jest? Read top to bottom. Just looking something up? Jump to the section you need.

All examples assume a simple module under test:

// math.js
function add(a, b) { return a + b; }
function divide(a, b) {
  if (b === 0) throw new Error("Cannot divide by zero");
  return a / b;
}
module.exports = { add, divide };

1. Structure: organizing your tests

test() / it() — define a single test

it() is just an alias for test(). Use whichever reads better; many people prefer it() because it makes the sentence flow (“it returns the sum”).

test('adds two numbers', () => {
  expect(add(2, 3)).toBe(5);
});

it('returns the sum of two numbers', () => {
  expect(add(2, 3)).toBe(5);
});

describe() — group related tests

Groups tests into a block so the output is readable and shared setup is scoped.

describe('add', () => {
  test('adds positive numbers', () => {
    expect(add(2, 3)).toBe(5);
  });

  test('handles negatives', () => {
    expect(add(-1, -1)).toBe(-2);
  });
});

Setup and teardown: beforeEach / afterEach / beforeAll / afterAll

beforeEach / afterEach run around every test in scope. beforeAll / afterAll run once for the whole block. Use the “each” variants to reset state between tests; use the “all” variants for expensive one-time setup like a DB connection.

describe('shopping cart', () => {
  let cart;

  beforeEach(() => {
    cart = [];            // fresh state for every test
  });

  afterEach(() => {
    cart = null;          // cleanup
  });

  test('starts empty', () => {
    expect(cart).toHaveLength(0);
  });
});

2. Assertions: expect() and matchers

expect(value) wraps the value you’re testing, then you chain a matcher that describes what you expect. You can negate any matcher with .not.

expect(add(2, 2)).toBe(4);
expect(add(2, 2)).not.toBe(5);

Equality

MatcherUse for
toBe()Strict equality (===) — primitives like numbers, strings, booleans
toEqual()Deep equality — objects and arrays (compares contents)
toStrictEqual()Like toEqual() but also checks types and undefined properties
expect(2 + 2).toBe(4);                          // primitive
expect({ a: 1 }).toEqual({ a: 1 });             // objects — toBe would FAIL here
expect([1, 2]).toEqual([1, 2]);                 // arrays
expect({ a: 1 }).toStrictEqual({ a: 1 });       // strictest

Gotcha: toBe() on two separate objects always fails because they’re different references in memory. Use toEqual() for anything that isn’t a primitive.

Truthiness

expect(true).toBeTruthy();
expect(0).toBeFalsy();
expect(null).toBeNull();
expect(undefined).toBeUndefined();
expect('hello').toBeDefined();

Numbers

expect(10).toBeGreaterThan(5);
expect(5).toBeLessThan(10);
expect(0.1 + 0.2).toBeCloseTo(0.3);   // float math — never use toBe here

toBeCloseTo() exists because 0.1 + 0.2 === 0.30000000000000004 in JavaScript. Use it for any floating-point comparison.

Strings and arrays

expect('team work').toContain('work');         // substring
expect(['a', 'b', 'c']).toContain('b');        // array membership
expect([1, 2, 3]).toHaveLength(3);
expect('2024-06-22').toMatch(/^\d{4}-\d{2}-\d{2}$/);  // regex

Objects

const user = { name: 'Vishal', roles: { admin: true } };
expect(user).toHaveProperty('name');
expect(user).toHaveProperty('name', 'Vishal');     // key + value
expect(user).toHaveProperty('roles.admin', true);  // nested path

Errors: toThrow()

The most common Jest mistake lives here. You must pass a function, not the result of calling it — otherwise the error throws before Jest can catch it.

// WRONG — throws immediately, test errors out
expect(divide(10, 0)).toThrow();

// RIGHT — wrap in an arrow function so Jest controls when it runs
expect(() => divide(10, 0)).toThrow();
expect(() => divide(10, 0)).toThrow('Cannot divide by zero');  // substring match
expect(() => divide(10, 0)).toThrow(Error);                    // by type

3. Async tests

A function that returns a promise needs special handling, or the test will pass before the promise settles.

async / await

async function fetchUser(id) {
  if (id < 0) throw new Error("Invalid id");
  return { id, name: "Alice" };
}

test('fetches a user', async () => {
  const user = await fetchUser(1);
  expect(user).toEqual({ id: 1, name: 'Alice' });
});

resolves / rejects

A cleaner style for asserting directly on a promise. Don’t forget the await — without it, a failing assertion can slip through silently.

test('resolves to a user', async () => {
  await expect(fetchUser(1)).resolves.toEqual({ id: 1, name: 'Alice' });
});

test('rejects on invalid id', async () => {
  await expect(fetchUser(-1)).rejects.toThrow('Invalid id');
});

4. Mocks

Mocks let you replace real dependencies (network calls, timers, other modules) with fakes you control, and then assert how they were used.

jest.fn() — a standalone mock function

test('calls the callback', () => {
  const callback = jest.fn();

  [1, 2, 3].forEach(callback);

  expect(callback).toHaveBeenCalled();
  expect(callback).toHaveBeenCalledTimes(3);
  expect(callback).toHaveBeenCalledWith(1, 0, [1, 2, 3]);
});

You can also control its return value:

const getId = jest.fn().mockReturnValue(42);
expect(getId()).toBe(42);

const fetchData = jest.fn().mockResolvedValue({ ok: true });
await expect(fetchData()).resolves.toEqual({ ok: true });

jest.spyOn() — watch (and optionally replace) a real method

Useful when you want to track calls to an existing method without rewriting it. Restore it afterward so other tests aren’t affected.

test('logs a warning', () => {
  const spy = jest.spyOn(console, 'warn').mockImplementation(() => {});

  console.warn('careful');

  expect(spy).toHaveBeenCalledWith('careful');
  spy.mockRestore();   // put the real method back
});

jest.mock() — replace an entire module

Mock out a whole dependency, like an HTTP client, so your tests never hit the network.

jest.mock('axios');
const axios = require('axios');

test('fetches users from the API', async () => {
  axios.get.mockResolvedValue({ data: [{ id: 1 }] });

  const res = await axios.get('/users');

  expect(res.data).toEqual([{ id: 1 }]);
  expect(axios.get).toHaveBeenCalledWith('/users');
});

Mock matchers at a glance

expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledTimes(2);
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');
expect(mockFn).toHaveBeenLastCalledWith('latest');

Quick reference

CategoryFunctions
Structuredescribetest / itbeforeEachafterEachbeforeAllafterAll
EqualitytoBetoEqualtoStrictEqual
TruthinesstoBeTruthytoBeFalsytoBeNulltoBeUndefinedtoBeDefined
NumberstoBeGreaterThantoBeLessThantoBeCloseTo
Strings/arraystoContaintoHaveLengthtoMatch
ObjectstoHavePropertytoEqual
ErrorstoThrow
Asyncasync/awaitresolvesrejects
Mocksjest.fnjest.spyOnjest.mock
Mock matcherstoHaveBeenCalledtoHaveBeenCalledTimestoHaveBeenCalledWith

Three mistakes worth memorizing: use toEqual (not toBe) for objects and arrays; wrap throwing calls in an arrow function for toThrow; and always await your resolves / rejects assertions.

Leave a Reply

Your email address will not be published. Required fields are marked *