Jest Testing Framework

Jest is a batteries-included JavaScript/TypeScript testing framework: a fast test runner, an expressive assertion library, built-in mocking, snapshot testing, and coverage — all with near-zero configuration. It's the long-standing default for React projects (and works with any JS codebase), pairing naturally with React Testing Library for component tests.

If you're on Vite, Vitest offers a near-identical API with faster startup; everything you learn here transfers. For the underlying principles, see Unit Testing and Mocking & Stubbing.

TL;DR

Quick Example

A test file is describe blocks of test cases with expect assertions:

Setup

Matchers

Async Tests

Mocking

Snapshot Testing

Update snapshots intentionally with jest --updateSnapshot. Inline snapshots (toMatchInlineSnapshot) keep the expected value next to the test.

⚠️ Use snapshots sparingly — they're easy to approve blindly and hard to maintain. Prefer explicit assertions for anything you can express directly.

Setup, Teardown & Coverage

Run jest --coverage (add --watch for rapid local feedback).

Testing React Components

Best Practices

Common Mistakes

Forgetting to await

Over-mocking

FAQ

Jest or Vitest — which should I use?

Use Jest for established projects, Create React App, Next.js, and anything not on Vite — it's mature, ubiquitous, and well-documented. Use Vitest for Vite-based apps where you want faster startup and native ESM/TS, with an almost identical API. The testing concepts are the same; the choice is mostly about your build tooling.

How do I test asynchronous code reliably?

Make the test async and await the operation (or return the promise), and use resolves/rejects matchers. The most common bug is forgetting to await — the test finishes before the assertion runs and falsely passes. For callbacks, use the done parameter and call it when complete, but prefer promises/async-await.

When should I use snapshot tests?

For stable, serializable output where an explicit assertion would be tedious — small config objects or component markup you want to guard against accidental change. Avoid large or frequently-changing snapshots: they get approved without review and become noise. Prefer targeted assertions (getByText, toHaveProperty) for anything you can state directly.

How do I avoid testing implementation details?

Assert on observable behavior — rendered text, returned values, calls to external boundaries — not on private state or internal method calls. With React Testing Library, query by role/text the way a user would, and drive interactions with userEvent. Tests written this way survive refactors and actually verify the thing users care about.

Related Topics

References