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
| Matcher | Use 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
| Category | Functions |
|---|---|
| Structure | describe, test / it, beforeEach, afterEach, beforeAll, afterAll |
| Equality | toBe, toEqual, toStrictEqual |
| Truthiness | toBeTruthy, toBeFalsy, toBeNull, toBeUndefined, toBeDefined |
| Numbers | toBeGreaterThan, toBeLessThan, toBeCloseTo |
| Strings/arrays | toContain, toHaveLength, toMatch |
| Objects | toHaveProperty, toEqual |
| Errors | toThrow |
| Async | async/await, resolves, rejects |
| Mocks | jest.fn, jest.spyOn, jest.mock |
| Mock matchers | toHaveBeenCalled, toHaveBeenCalledTimes, toHaveBeenCalledWith |
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.