# Code Reference — Jest

_21 pages_

---
# Jest (/docs/jest)



# Jest [#jest]

JavaScript testing framework.

Browse the sidebar for every cheat sheet in this section.

## Sections [#sections]

* [Examples](./examples)


---

# Async (/docs/jest/async)



# Async [#async]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Jest supports promises, async/await, and callbacks (`done`). Prefer returning/awaiting promises; use `.resolves` / `.rejects` matchers for clarity.

## 🔧 Core concepts [#-core-concepts]

| Style            | Pattern                              |
| ---------------- | ------------------------------------ |
| async/await      | `await` inside `test`                |
| Promise return   | `return fetch().then(...)`           |
| resolves/rejects | `await expect(p).resolves.toBe(...)` |
| done             | Legacy callbacks — avoid if possible |
| Fake timers      | Interact carefully with promises     |

Unhandled rejections fail the test when properly awaited.

## 💡 Examples [#-examples]

**async/await:**

```js
test('loads user', async () => {
  const user = await api.getUser(1);
  expect(user.id).toBe(1);
});
```

**resolves / rejects:**

```js
await expect(api.getUser(1)).resolves.toMatchObject({ id: 1 });
await expect(api.getUser(-1)).rejects.toThrow(/not found/);
await expect(api.getUser(-1)).rejects.toMatchObject({ status: 404 });
```

**Promise return (no async):**

```js
test('ok', () => {
  return api.ping().then((r) => expect(r).toBe('pong'));
});
```

**Timeouts:**

```js
test('slow', async () => {
  await longJob();
}, 15_000);
```

**Concurrent (Jest 29+):**

```js
test.concurrent('a', async () => { /* ... */ });
test.concurrent('b', async () => { /* ... */ });
```

## ⚠️ Pitfalls [#️-pitfalls]

* Missing `await` / `return` → false green tests.
* Mixing `done` with promises incorrectly.
* Asserting before microtasks flush — await or `await Promise.resolve()`.
* Fake timers + real promises deadlocks without `advanceTimers`.
* Swallowing errors in try/catch without rethrow/expect.

## 🔗 Related [#-related]

* [Matchers](/docs/jest/matchers)
* [Timers](/docs/jest/timers)
* [Mocks](/docs/jest/mocks)
* [Spies](/docs/jest/spies)
* [Setup & teardown](/docs/jest/setup-teardown)
* [React Testing Library](/docs/jest/react-testing-library)


---

# Config (/docs/jest/config)



# Config [#config]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Configure Jest via `jest.config.js/ts` or `package.json#jest`. Key knobs: environment, transforms, roots, coverage, and setup files.

## 🔧 Core concepts [#-core-concepts]

| Option                | Purpose                  |
| --------------------- | ------------------------ |
| `testEnvironment`     | `node` \| `jsdom`        |
| `roots` / `testMatch` | Discovery                |
| `transform`           | TS/JS compile            |
| `moduleNameMapper`    | Aliases / CSS mocks      |
| `setupFilesAfterEnv`  | Matchers, RTL            |
| `collectCoverageFrom` | Coverage scope           |
| `clearMocks`          | Auto clear between tests |

## 💡 Examples [#-examples]

**jest.config.js:**

```js
/** @type {import('jest').Config} */
module.exports = {
  testEnvironment: 'node',
  roots: ['<rootDir>/src'],
  testMatch: ['**/__tests__/**/*.test.ts'],
  clearMocks: true,
  collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.d.ts'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '\\.(css|less)$': 'identity-obj-proxy',
  },
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
};
```

**React / jsdom:**

```js
testEnvironment: 'jsdom',
```

**package.json scripts:**

```json
{
  "scripts": {
    "test": "jest",
    "test:ci": "jest --ci --coverage --maxWorkers=2"
  }
}
```

**CLI overrides:**

```shellscript
npx jest --config=jest.config.js
npx jest --env=jsdom
npx jest --runInBand
```

## ⚠️ Pitfalls [#️-pitfalls]

* Path aliases in TS not mirrored in `moduleNameMapper`.
* Transforming `node_modules` accidentally (slow) or not transforming ESM deps.
* Multiple configs in monorepos without projects/`--selectProjects`.
* `jsdom` for pure Node libraries — unnecessary overhead.
* Coverage thresholds failing CI without local awareness.

## 🔗 Related [#-related]

* [Install](/docs/jest/install)
* [TypeScript](/docs/jest/typescript)
* [Coverage](/docs/jest/coverage)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Module mocks](/docs/jest/module-mocks)
* [Watch mode](/docs/jest/watch-mode)


---

# Coverage (/docs/jest/coverage)



# Coverage [#coverage]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Jest ships coverage via Istanbul/V8 providers. Collect with `--coverage`, set thresholds, and emit HTML/LCOV for CI.

## 🔧 Core concepts [#-core-concepts]

| Option                | Role             |
| --------------------- | ---------------- |
| `--coverage`          | Enable           |
| `collectCoverageFrom` | Include globs    |
| `coverageThreshold`   | Fail under %     |
| `coverageProvider`    | `babel` \| `v8`  |
| `coverageReporters`   | html, text, lcov |

Ignore generated files and stories in `coveragePathIgnorePatterns`.

## 💡 Examples [#-examples]

**CLI:**

```shellscript
npx jest --coverage
npx jest --coverage --collectCoverageFrom='src/**/*.{ts,tsx}'
```

**Config thresholds:**

```js
module.exports = {
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
    '!src/**/*.stories.*',
  ],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },
  coverageReporters: ['text', 'lcov', 'html'],
};
```

**CI:**

```shellscript
npx jest --ci --coverage --maxWorkers=2
```

Open `coverage/lcov-report/index.html` locally.

## ⚠️ Pitfalls [#️-pitfalls]

* Inflated coverage from trivial barrel files.
* V8 vs babel provider differences on ignored lines.
* Thresholds on empty suites passing vacuously.
* Not gitignoring `coverage/`.
* Collecting from `dist/` instead of `src/`.

## 🔗 Related [#-related]

* [Config](/docs/jest/config)
* [Watch mode](/docs/jest/watch-mode)
* [Install](/docs/jest/install)
* [TypeScript](/docs/jest/typescript)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Migration to Vitest](/docs/jest/migration-vitest)


---

# Custom Matchers (/docs/jest/custom-matchers)



# Custom Matchers [#custom-matchers]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Extend `expect` with domain matchers via `expect.extend`. Ship them from `setupFilesAfterEnv` so every test can use readable assertions.

## 🔧 Core concepts [#-core-concepts]

| Piece           | Role                    |
| --------------- | ----------------------- |
| `expect.extend` | Register matchers       |
| `this.isNot`    | Negation support        |
| `this.utils`    | Diff / print helpers    |
| TypeScript      | Augment `jest.Matchers` |
| jest-dom        | Ready-made DOM matchers |

Return `\{ pass, message \}` from matcher functions.

## 💡 Examples [#-examples]

**Define:**

```js
// matchers/toBeWithinRange.js
expect.extend({
  toBeWithinRange(received, floor, ceiling) {
    const pass = received >= floor && received <= ceiling;
    return {
      pass,
      message: () =>
        pass
          ? `expected ${received} not to be within ${floor}-${ceiling}`
          : `expected ${received} to be within ${floor}-${ceiling}`,
    };
  },
});
```

**Setup:**

```js
// jest.setup.js
require('./matchers/toBeWithinRange');
```

**Use:**

```js
expect(100).toBeWithinRange(90, 110);
expect(50).not.toBeWithinRange(90, 110);
```

**TypeScript declaration:**

```ts
declare global {
  namespace jest {
    interface Matchers<R> {
      toBeWithinRange(floor: number, ceiling: number): R;
    }
  }
}
export {};
```

**Async matchers:** return a Promise of `\{ pass, message \}` for `.resolves` chains when needed.

## ⚠️ Pitfalls [#️-pitfalls]

* Mutating global expect without setup file — matchers missing in some workers.
* Poor `message` functions making failures opaque.
* Ignoring `this.isNot` leading to wrong negation text.
* Conflicting matcher names with jest-dom.
* Forgetting to export types for TS projects.

## 🔗 Related [#-related]

* [Matchers](/docs/jest/matchers)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Config](/docs/jest/config)
* [React Testing Library](/docs/jest/react-testing-library)
* [Snapshots](/docs/jest/snapshots)
* [TypeScript](/docs/jest/typescript)


---

# Examples (/docs/jest/examples)



# Examples [#examples]

Jest notes in **Examples**.


---

# Async User Event (/docs/jest/examples/async-user-event)



# Async User Event [#async-user-event]

*Jest · Example / how-to*

***

## 📋 Overview [#-overview]

Test interactive React (or DOM) flows with `@testing-library/user-event` and async `findBy*` queries.

## 🔧 Core concepts [#-core-concepts]

| Piece               | Role                   |
| ------------------- | ---------------------- |
| `userEvent.setup()` | Realistic interactions |
| `await user.click`  | Async event API        |
| `findBy*`           | Wait for UI updates    |
| `await` assertions  | Flush promises         |

## 💡 Examples [#-examples]

**AsyncSearch.tsx (component under test):**

```tsx
import { useState } from "react";

export function AsyncSearch({ onSearch }: { onSearch: (q: string) => Promise<string[]> }) {
  const [items, setItems] = useState<string[]>([]);
  const [status, setStatus] = useState("idle");

  async function handleClick() {
    setStatus("loading");
    const next = await onSearch("ada");
    setItems(next);
    setStatus("done");
  }

  return (
    <div>
      <button type="button" onClick={handleClick}>
        Search
      </button>
      <p>{status}</p>
      <ul>
        {items.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
```

**AsyncSearch.test.tsx:**

```tsx
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { AsyncSearch } from "./AsyncSearch";

test("loads results after click", async () => {
  const user = userEvent.setup();
  const onSearch = jest.fn().mockResolvedValue(["Ada Lovelace"]);

  render(<AsyncSearch onSearch={onSearch} />);
  await user.click(screen.getByRole("button", { name: "Search" }));

  expect(await screen.findByText("Ada Lovelace")).toBeInTheDocument();
  expect(screen.getByText("done")).toBeInTheDocument();
  expect(onSearch).toHaveBeenCalledWith("ada");
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Prefer `userEvent` over `fireEvent` for closer-to-real typing/clicking.
* Use `findBy*` for async UI; `getBy*` throws immediately if missing.
* Always `await` user-event methods in the v14+ async API.

## 🔗 Related [#-related]

* [Mock module](/docs/jest/examples/mock-module)


---

# Mock Module (/docs/jest/examples/mock-module)



# Mock Module [#mock-module]

*Jest · Example / how-to*

***

## 📋 Overview [#-overview]

Replace a module dependency with `jest.mock` so unit tests control return values and assert call shapes.

## 🔧 Core concepts [#-core-concepts]

| Piece        | Role                    |
| ------------ | ----------------------- |
| `jest.mock`  | Hoisted module stub     |
| `jest.fn`    | Spy / stub function     |
| `mocked()`   | Typed mock helpers (TS) |
| `beforeEach` | Reset call history      |

## 💡 Examples [#-examples]

**api.ts:**

```typescript
export async function fetchUser(id: string) {
  const res = await fetch(`/api/users/${id}`);
  if (!res.ok) throw new Error("fail");
  return res.json();
}
```

**userService.ts:**

```typescript
import { fetchUser } from "./api";

export async function getUserLabel(id: string) {
  const user = await fetchUser(id);
  return `${user.name} <${user.email}>`;
}
```

**userService.test.ts:**

```typescript
import { getUserLabel } from "./userService";
import { fetchUser } from "./api";

jest.mock("./api");

const fetchUserMock = fetchUser as jest.MockedFunction<typeof fetchUser>;

beforeEach(() => {
  fetchUserMock.mockReset();
});

test("formats label from API user", async () => {
  fetchUserMock.mockResolvedValue({
    name: "Ada",
    email: "ada@example.com",
  });

  await expect(getUserLabel("1")).resolves.toBe("Ada <ada@example.com>");
  expect(fetchUserMock).toHaveBeenCalledWith("1");
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* `jest.mock` is hoisted — keep factories self-contained.
* Forget `mockReset` / `clearAllMocks` and tests leak state.
* Mock the module boundary your unit owns; avoid mocking huge frameworks casually.

## 🔗 Related [#-related]

* [Async user event](/docs/jest/examples/async-user-event)


---

# Glossary (/docs/jest/glossary)



# Glossary [#glossary]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Alphabetical glossary of core Jest terms for matchers, mocks, lifecycle hooks, snapshots, and test configuration.

## 🔧 Core concepts [#-core-concepts]

| Term             | Definition                                                                            |
| ---------------- | ------------------------------------------------------------------------------------- |
| AfterAll         | A hook that runs once after all tests in a file or `describe` finish.                 |
| AfterEach        | A hook that runs after every test in the current scope.                               |
| BeforeAll        | A hook that runs once before any tests in a file or `describe` start.                 |
| BeforeEach       | A hook that runs before every test in the current scope.                              |
| Coverage         | A report of which statements/branches tests executed.                                 |
| Describe         | A block that groups related tests under a shared name.                                |
| Each             | A helper (`test.each` / `describe.each`) that table-drives repeated cases.            |
| Expect           | The assertion entry point that chains matchers onto a value.                          |
| Fake timers      | Mocked clock APIs that let tests advance time manually.                               |
| Fn               | `jest.fn()`, the factory for mock functions.                                          |
| Hoisting         | Jest’s behavior of lifting `jest.mock` calls to the top of a module.                  |
| It / test        | A single test case function registered with Jest.                                     |
| Matcher          | An assertion method such as `toBe`, `toEqual`, or `toHaveBeenCalled`.                 |
| Mock             | A stand-in function or module that records calls and controls returns.                |
| Module mock      | Replacing an imported module with a mock via `jest.mock`.                             |
| Only / skip      | Focusing (`.only`) or excluding (`.skip`) specific suites or tests.                   |
| Setup file       | A file run before the test framework is installed in each environment.                |
| Snapshot         | A serialized output stored on disk and compared on later runs.                        |
| Spy              | A wrapper around a real function that records calls while optionally calling through. |
| Suite            | A group of tests, typically created by a `describe` block.                            |
| Test environment | The runtime context such as `node` or `jsdom` for each test file.                     |
| Test runner      | The component that discovers files and executes suites.                               |
| Timeout          | The maximum duration a test may run before Jest fails it.                             |
| Transformer      | A preprocessor (often Babel/ts-jest) that compiles files before tests.                |
| Watch mode       | A continuous mode that re-runs affected tests on file changes.                        |

## 💡 Examples [#-examples]

**Describe, test, and matchers:**

```js
describe("sum", () => {
  test("adds numbers", () => {
    expect(1 + 2).toBe(3);
    expect({ a: 1 }).toEqual({ a: 1 });
  });
});
```

**Mocks and spies:**

```js
const fetchUser = jest.fn().mockResolvedValue({ id: 1 });
const log = jest.spyOn(console, "log").mockImplementation(() => {});

await fetchUser(1);
expect(fetchUser).toHaveBeenCalledWith(1);
log.mockRestore();
```

**Lifecycle hooks:**

```js
beforeEach(() => {
  jest.clearAllMocks();
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Confusing &#x2A;*`toBe`*&#x2A; (reference/primitive identity) with &#x2A;*`toEqual`** (deep value equality).
* Mixing **mock** (full replacement) with **spy** (wrap existing implementation).
* Treating **snapshot** failures as always product bugs — snapshots need intentional updates.
* Equating **fake timers** with real delays — you must advance timers explicitly.
* Assuming **clearAllMocks** resets implementations the same way **resetAllMocks** does.

## 🔗 Related [#-related]

* [matchers](/docs/jest/matchers)
* [mocks](/docs/jest/mocks)
* [spies](/docs/jest/spies)
* [setup\_teardown](/docs/jest/setup-teardown)
* [snapshots](/docs/jest/snapshots)
* [watch\_mode](/docs/jest/watch-mode)


---

# Install (/docs/jest/install)



# Install [#install]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Jest is a zero/low-config JavaScript test runner with assertions, mocks, snapshots, and coverage. Install as a dev dependency; use `jest` or `npm test` via scripts.

## 🔧 Core concepts [#-core-concepts]

| Package                  | Role                    |
| ------------------------ | ----------------------- |
| `jest`                   | Runner + expect + mocks |
| `babel-jest`             | Transform modern JS     |
| `ts-jest` / `@swc/jest`  | TypeScript              |
| `jest-environment-jsdom` | DOM for React           |

Jest 29+ is common; check your major for config keys.

## 💡 Examples [#-examples]

**Install:**

```shellscript
npm i -D jest @types/jest
# TypeScript:
npm i -D ts-jest typescript
# React DOM env:
npm i -D jest-environment-jsdom
```

**package.json:**

```json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage"
  }
}
```

**First test:**

```js
// sum.test.js
const sum = (a, b) => a + b;

test('adds', () => {
  expect(sum(1, 2)).toBe(3);
});
```

**Init config:**

```shellscript
npx jest --init
```

**Run:**

```shellscript
npx jest
npx jest sum.test.js
npx jest -t "adds"
```

## ⚠️ Pitfalls [#️-pitfalls]

* Running an old global `jest` instead of the project binary.
* Missing transform for ESM/TS — tests fail to parse.
* Confusing Vitest APIs when both exist in a monorepo.
* Not setting `testEnvironment` for DOM code (`node` vs `jsdom`).
* Committing huge coverage folders — gitignore them.

## 🔗 Related [#-related]

* [Config](/docs/jest/config)
* [Matchers](/docs/jest/matchers)
* [TypeScript](/docs/jest/typescript)
* [Watch mode](/docs/jest/watch-mode)
* [Coverage](/docs/jest/coverage)
* [Migration to Vitest](/docs/jest/migration-vitest)


---

# Matchers (/docs/jest/matchers)



# Matchers [#matchers]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`expect(value)` matchers assert equality, truthiness, numbers, strings, collections, and errors. Prefer asymmetric matchers for partial object checks.

## 🔧 Core concepts [#-core-concepts]

| Matcher                 | Use                                    |
| ----------------------- | -------------------------------------- |
| `toBe`                  | Referential / primitives (`Object.is`) |
| `toEqual`               | Deep equality                          |
| `toStrictEqual`         | Deep + undefined keys                  |
| `toMatch` / `toContain` | String / array                         |
| `toThrow`               | Sync exceptions                        |
| `toBeCloseTo`           | Floats                                 |
| `toHaveBeenCalled`      | Mocks                                  |

Chain `.not`, `.resolves`, `.rejects`.

## 💡 Examples [#-examples]

**Equality:**

```js
expect(1 + 1).toBe(2);
expect({ a: 1 }).toEqual({ a: 1 });
expect({ a: 1 }).toStrictEqual({ a: 1 });
```

**Truthiness & numbers:**

```js
expect(x).toBeTruthy();
expect(x).toBeNull();
expect(x).toBeUndefined();
expect(0.1 + 0.2).toBeCloseTo(0.3);
expect(score).toBeGreaterThan(10);
```

**Collections & strings:**

```js
expect(['a', 'b']).toContain('a');
expect('hello').toMatch(/ell/);
expect({ a: 1, b: 2 }).toMatchObject({ a: 1 });
expect([{ id: 1 }]).toContainEqual({ id: 1 });
```

**Asymmetric:**

```js
expect(user).toEqual({
  id: expect.any(Number),
  email: expect.stringMatching(/@/),
  meta: expect.objectContaining({ role: 'admin' }),
});
```

**Errors:**

```js
expect(() => parse('')).toThrow(Error);
expect(() => parse('')).toThrow(/empty/);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `toBe` on objects compares references — use `toEqual`.
* Floating point with `toBe` — use `toBeCloseTo`.
* `toThrow` needs a wrapped function, not a thrown call.
* Over-specific snapshots instead of focused matchers.
* Forgetting `await expect(...).resolves` for promises.

## 🔗 Related [#-related]

* [Async](/docs/jest/async)
* [Mocks](/docs/jest/mocks)
* [Custom matchers](/docs/jest/custom-matchers)
* [Snapshots](/docs/jest/snapshots)
* [Spies](/docs/jest/spies)
* [Install](/docs/jest/install)


---

# Migration to Vitest (/docs/jest/migration-vitest)



# Migration to Vitest [#migration-to-vitest]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Vitest is Jest-compatible for many APIs (`describe`, `expect`, `vi.fn`) with Vite-native ESM speed. Migrate incrementally: install Vitest, map config, replace Jest globals, fix mocks.

## 🔧 Core concepts [#-core-concepts]

| Jest                 | Vitest                 |
| -------------------- | ---------------------- |
| `jest.fn`            | `vi.fn`                |
| `jest.mock`          | `vi.mock`              |
| `jest.spyOn`         | `vi.spyOn`             |
| `jest.useFakeTimers` | `vi.useFakeTimers`     |
| `jest.config.js`     | `vitest.config.ts`     |
| `jsdom` env          | `environment: 'jsdom'` |

Keep `@testing-library/*` — works with both.

## 💡 Examples [#-examples]

**Install:**

```shellscript
npm i -D vitest jsdom @vitest/coverage-v8
```

**vitest.config.ts:**

```ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./vitest.setup.ts'],
    coverage: { provider: 'v8', reporter: ['text', 'html'] },
  },
});
```

**API swap:**

```ts
// before
jest.spyOn(api, 'get').mockResolvedValue(1);
// after
import { vi } from 'vitest';
vi.spyOn(api, 'get').mockResolvedValue(1);
```

**Scripts:**

```json
{
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest"
  }
}
```

**Codemod mindset:** replace `jest.` → `vi.`, update snapshot paths, re-check module mocks under ESM.

## ⚠️ Pitfalls [#️-pitfalls]

* Assuming 100% Jest mock hoisting parity under native ESM.
* Leaving `@types/jest` conflicting with Vitest types.
* Transforming with Jest while running Vitest (duplicate configs).
* Coverage provider/path differences breaking CI thresholds.
* Migrating everything at once — prefer package-by-package in monorepos.

## 🔗 Related [#-related]

* [Install](/docs/jest/install)
* [Config](/docs/jest/config)
* [Mocks](/docs/jest/mocks)
* [Module mocks](/docs/jest/module-mocks)
* [TypeScript](/docs/jest/typescript)
* [Coverage](/docs/jest/coverage)


---

# Mocks (/docs/jest/mocks)



# Mocks [#mocks]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`jest.fn` and `jest.mock` replace dependencies with controllable fakes. Track calls, set return values, and restore with `clearAllMocks` / `restoreAllMocks`.

## 🔧 Core concepts [#-core-concepts]

| API                                     | Role                  |
| --------------------------------------- | --------------------- |
| `jest.fn()`                             | Mock function         |
| `jest.mock(path)`                       | Module mock (hoisted) |
| `jest.spyOn`                            | Wrap existing method  |
| `mockReturnValue` / `mockResolvedValue` | Outputs               |
| `mockImplementation`                    | Custom body           |

Manual mocks live in `__mocks__` beside modules.

## 💡 Examples [#-examples]

**jest.fn:**

```js
const send = jest.fn().mockReturnValue(true);
send('hi');
expect(send).toHaveBeenCalledWith('hi');
expect(send).toHaveBeenCalledTimes(1);
```

**Async mock:**

```js
const fetchUser = jest
  .fn()
  .mockResolvedValue({ id: 1 })
  .mockRejectedValueOnce(new Error('network'));
```

**Module mock:**

```js
jest.mock('./api', () => ({
  getUser: jest.fn().mockResolvedValue({ id: 1 }),
}));

import { getUser } from './api';

test('uses mock', async () => {
  await expect(getUser()).resolves.toEqual({ id: 1 });
});
```

**Partial mock:**

```js
jest.mock('./utils', () => {
  const actual = jest.requireActual('./utils');
  return { ...actual, randomId: () => 'fixed' };
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* `jest.mock` is hoisted — don't rely on runtime vars above it without `jest.doMock`.
* Forgetting to reset mocks between tests → cross-test pollution.
* Mocking the wrong path (definition vs import site).
* Over-mocking until nothing real is tested.
* ESM + Jest mocking needs experimental/transform setup.

## 🔗 Related [#-related]

* [Spies](/docs/jest/spies)
* [Module mocks](/docs/jest/module-mocks)
* [Matchers](/docs/jest/matchers)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Async](/docs/jest/async)
* [Custom matchers](/docs/jest/custom-matchers)


---

# Module Mocks (/docs/jest/module-mocks)



# Module Mocks [#module-mocks]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Automock modules with `jest.mock`, manual `__mocks__` folders, and virtual mocks. Control Node built-ins and CSS/assets via mappers.

## 🔧 Core concepts [#-core-concepts]

| Technique                  | When                 |
| -------------------------- | -------------------- |
| `jest.mock('./mod')`       | Auto mock or factory |
| `__mocks__/mod.js`         | Shared manual mock   |
| `jest.requireActual`       | Partial mock         |
| `moduleNameMapper`         | Assets / aliases     |
| `jest.unstable_mockModule` | ESM (experimental)   |

Factories run in a sandboxed scope; hoist rules apply to `jest.mock`.

## 💡 Examples [#-examples]

**Manual mock:**

```plaintext
src/
  api.js
  __mocks__/
    api.js
```

```js
// __mocks__/api.js
export const getUser = jest.fn();
```

```js
jest.mock('./api');
import { getUser } from './api';
getUser.mockResolvedValue({ id: 1 });
```

**Virtual mock:**

```js
jest.mock('analytics', () => ({ track: jest.fn() }), { virtual: true });
```

**Asset mapper:**

```js
moduleNameMapper: {
  '\\.svg$': '<rootDir>/test/svgrMock.js',
  '\\.(css)$': 'identity-obj-proxy',
},
```

**Unmock / isolate:**

```js
jest.unmock('./api');
jest.isolateModules(() => {
  const mod = require('./fresh');
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Factory referencing out-of-scope variables (TDZ / hoist).
* Manual mocks not picked up because path casing/OS differs.
* Mocking ESM named exports incorrectly (namespace shape).
* Leaving automock on globally (`automock: true`) — surprising.
* Circular deps with `requireActual` causing partial undefineds.

## 🔗 Related [#-related]

* [Mocks](/docs/jest/mocks)
* [Spies](/docs/jest/spies)
* [Config](/docs/jest/config)
* [TypeScript](/docs/jest/typescript)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Migration to Vitest](/docs/jest/migration-vitest)


---

# React Testing Library (/docs/jest/react-testing-library)



# React Testing Library [#react-testing-library]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Testing Library tests React the way users interact: roles, labels, text — not implementation details. Pair with Jest + `jsdom` and `@testing-library/jest-dom`.

## 🔧 Core concepts [#-core-concepts]

| API                   | Role                   |
| --------------------- | ---------------------- |
| `render`              | Mount component        |
| `screen`              | Queries on document    |
| `userEvent`           | Realistic interactions |
| `waitFor` / `findBy*` | Async UI               |
| `within`              | Scope queries          |

Prefer `getByRole` → `getByLabelText` → `getByText` → `getByTestId`.

## 💡 Examples [#-examples]

**Install:**

```shellscript
npm i -D @testing-library/react @testing-library/jest-dom @testing-library/user-event jest-environment-jsdom
```

```js
// jest.setup.js
import '@testing-library/jest-dom';
```

**Component test:**

```tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Login } from './Login';

test('submits email', async () => {
  const user = userEvent.setup();
  const onSubmit = jest.fn();
  render(<Login onSubmit={onSubmit} />);

  await user.type(screen.getByLabelText(/email/i), 'ada@ex.com');
  await user.click(screen.getByRole('button', { name: /sign in/i }));

  expect(onSubmit).toHaveBeenCalledWith({ email: 'ada@ex.com' });
});
```

**Async:**

```tsx
expect(await screen.findByText(/welcome/i)).toBeInTheDocument();
await waitFor(() => expect(mock).toHaveBeenCalled());
```

## ⚠️ Pitfalls [#️-pitfalls]

* Querying by className / enzyme-style selectors.
* Forgetting `userEvent.setup()` with fake timers.
* Not wrapping state updates that warn about act — usually fixed by `findBy`/`await user`.
* Snapshotting entire `container.innerHTML` instead of behavior asserts.
* Using `getBy*` for elements that appear asynchronously — use `findBy*`.

## 🔗 Related [#-related]

* [Matchers](/docs/jest/matchers)
* [Async](/docs/jest/async)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Config](/docs/jest/config)
* [Timers](/docs/jest/timers)
* [Snapshots](/docs/jest/snapshots)


---

# Setup & Teardown (/docs/jest/setup-teardown)



# Setup & Teardown [#setup--teardown]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`beforeAll` / `beforeEach` / `afterEach` / `afterAll` manage lifecycle. Keep setup local to `describe` blocks; reset mocks and state so tests stay independent.

## 🔧 Core concepts [#-core-concepts]

| Hook         | When                |
| ------------ | ------------------- |
| `beforeAll`  | Once before suite   |
| `beforeEach` | Before every test   |
| `afterEach`  | After every test    |
| `afterAll`   | Once after suite    |
| `describe`   | Scope hooks & tests |

Order: outer `beforeAll` → inner `beforeAll` → `beforeEach` → test → `afterEach` → …

## 💡 Examples [#-examples]

**Typical cleanup:**

```js
beforeEach(() => {
  jest.clearAllMocks();
});

afterEach(() => {
  jest.useRealTimers();
  cleanup(); // RTL
});
```

**Scoped describe:**

```js
describe('db', () => {
  let db;
  beforeAll(async () => {
    db = await connect();
  });
  afterAll(async () => {
    await db.close();
  });
  test('query', async () => {
    expect(await db.ping()).toBe(true);
  });
});
```

**Global setup files (config):**

```js
// jest.config.js
setupFiles: ['<rootDir>/jest.polyfills.js'],
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
```

```js
// jest.setup.js
import '@testing-library/jest-dom';
```

**Skip / only:**

```js
describe.skip('wip', () => {});
test.only('focus', () => {});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Shared mutable state in `beforeAll` without reset.
* Async hooks without `async`/`await` → races.
* Leaving `test.only` in committed code.
* Heavy `beforeEach` making suites slow — prefer lighter factories.
* Global setup importing app modules before mocks are declared.

## 🔗 Related [#-related]

* [Config](/docs/jest/config)
* [Mocks](/docs/jest/mocks)
* [Timers](/docs/jest/timers)
* [React Testing Library](/docs/jest/react-testing-library)
* [Module mocks](/docs/jest/module-mocks)
* [Watch mode](/docs/jest/watch-mode)


---

# Snapshots (/docs/jest/snapshots)



# Snapshots [#snapshots]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Snapshots store serialized output and fail when it changes. Use for UI trees, large JSON, or error messages — keep them small and review diffs in PRs.

## 🔧 Core concepts [#-core-concepts]

| API                            | Use                        |
| ------------------------------ | -------------------------- |
| `toMatchSnapshot`              | File under `__snapshots__` |
| `toMatchInlineSnapshot`        | Embedded in test file      |
| `toThrowErrorMatchingSnapshot` | Error text                 |
| `-u` / `--updateSnapshot`      | Refresh baselines          |
| Property matchers              | Soften volatile fields     |

Prefer inline snapshots for tiny values; file snapshots for larger trees.

## 💡 Examples [#-examples]

**Basic:**

```js
test('renders', () => {
  expect(renderHeader()).toMatchSnapshot();
});
```

**Inline:**

```js
expect(user).toMatchInlineSnapshot(`
{
  "id": 1,
  "name": "Ada",
}
`);
```

**Property matchers:**

```js
expect(article).toMatchSnapshot({
  id: expect.any(Number),
  createdAt: expect.any(Date),
});
```

**Update:**

```shellscript
npx jest -u
npx jest path/to/file.test.js -u
```

**Serializer (custom):**

```js
expect.addSnapshotSerializer({
  test: (v) => v && v.__type === 'Money',
  print: (v) => `Money(${v.cents})`,
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Giant DOM snapshots that churn on class-name noise.
* Blindly updating with `-u` without reading diffs.
* Timestamps/random IDs without property matchers.
* Committing snapshots that differ by OS line endings.
* Using snapshots instead of precise matchers for critical logic.

## 🔗 Related [#-related]

* [Matchers](/docs/jest/matchers)
* [React Testing Library](/docs/jest/react-testing-library)
* [Custom matchers](/docs/jest/custom-matchers)
* [Watch mode](/docs/jest/watch-mode)
* [Config](/docs/jest/config)
* [Coverage](/docs/jest/coverage)


---

# Spies (/docs/jest/spies)



# Spies [#spies]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`jest.spyOn(object, method)` wraps a real method to assert calls while optionally keeping the original implementation. Prefer spies when you need partial observation.

## 🔧 Core concepts [#-core-concepts]

| API                    | Effect                         |
| ---------------------- | ------------------------------ |
| `jest.spyOn(obj, 'm')` | Track calls                    |
| `mockImplementation`   | Replace body                   |
| `mockRestore`          | Put original back              |
| `mockClear`            | Clear call history             |
| `mockReset`            | Clear history + implementation |

Spies are mocks; matchers like `toHaveBeenCalledWith` apply.

## 💡 Examples [#-examples]

**Observe without changing:**

```js
const log = jest.spyOn(console, 'log').mockImplementation(() => {});
doWork();
expect(log).toHaveBeenCalledWith('done');
log.mockRestore();
```

**Replace temporarily:**

```js
const spy = jest
  .spyOn(Date, 'now')
  .mockReturnValue(1_700_000_000_000);
expect(Date.now()).toBe(1_700_000_000_000);
spy.mockRestore();
```

**Class method:**

```js
const spy = jest.spyOn(User.prototype, 'save').mockResolvedValue(undefined);
await user.save();
expect(spy).toHaveBeenCalled();
```

**Cleanup in afterEach:**

```js
afterEach(() => {
  jest.restoreAllMocks();
});
```

**Call order:**

```js
expect(fnA.mock.invocationCallOrder[0]).toBeLessThan(
  fnB.mock.invocationCallOrder[0],
);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Spying on non-configurable properties / some ESM bindings.
* Leaving `console` spies mocked and hiding useful output.
* `mockReset` vs `mockRestore` confusion — restore for spies.
* Spying after the module cached a bound original function.
* Asserting call order in parallel async code.

## 🔗 Related [#-related]

* [Mocks](/docs/jest/mocks)
* [Module mocks](/docs/jest/module-mocks)
* [Matchers](/docs/jest/matchers)
* [Timers](/docs/jest/timers)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Async](/docs/jest/async)


---

# Timers (/docs/jest/timers)



# Timers [#timers]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Fake timers control `setTimeout`, `setInterval`, and (with modern APIs) `Date`. Use them to test debouncing, polling, and animations without real waits.

## 🔧 Core concepts [#-core-concepts]

| API                    | Role            |
| ---------------------- | --------------- |
| `jest.useFakeTimers()` | Enable fakes    |
| `jest.useRealTimers()` | Restore real    |
| `advanceTimersByTime`  | Fast-forward ms |
| `runAllTimers`         | Flush all       |
| `runOnlyPendingTimers` | Current queue   |
| `modern` / legacy      | Fake timer impl |

Jest 29 defaults to modern `@sinonjs/fake-timers`.

## 💡 Examples [#-examples]

**Debounce:**

```js
jest.useFakeTimers();

test('debounces', () => {
  const fn = jest.fn();
  const d = debounce(fn, 500);
  d();
  d();
  expect(fn).not.toHaveBeenCalled();
  jest.advanceTimersByTime(500);
  expect(fn).toHaveBeenCalledTimes(1);
});

afterEach(() => {
  jest.useRealTimers();
});
```

**Async + timers:**

```js
test('polls', async () => {
  jest.useFakeTimers();
  const p = waitForReady(); // uses setTimeout
  await jest.advanceTimersByTimeAsync(1000);
  await expect(p).resolves.toBe(true);
});
```

**Fake Date:**

```js
jest.useFakeTimers({ now: new Date('2020-01-01') });
expect(Date.now()).toBe(new Date('2020-01-01').getTime());
```

**Config:**

```js
// jest.config.js
fakeTimers: { enableGlobally: false },
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `useRealTimers` → later tests hang or flake.
* Mixing real promises with fake timers without `advanceTimersByTimeAsync`.
* `runAllTimers` infinite loops on recurring intervals.
* User-event / RTL needs `advanceTimers` coordination.
* Spying on `Date` while also faking timers — pick one strategy.

## 🔗 Related [#-related]

* [Async](/docs/jest/async)
* [Mocks](/docs/jest/mocks)
* [Spies](/docs/jest/spies)
* [Setup & teardown](/docs/jest/setup-teardown)
* [React Testing Library](/docs/jest/react-testing-library)
* [Config](/docs/jest/config)


---

# TypeScript (/docs/jest/typescript)



# TypeScript [#typescript]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Run TypeScript tests with `ts-jest`, `@swc/jest`, or Babel. Keep `tsconfig` and Jest transforms aligned for path aliases and JSX.

## 🔧 Core concepts [#-core-concepts]

| Approach     | Notes                            |
| ------------ | -------------------------------- |
| `ts-jest`    | Type-aware option; slower        |
| `@swc/jest`  | Fast transpile                   |
| `babel-jest` | Shared Babel pipeline            |
| Types        | `@types/jest` or `@jest/globals` |

Prefer transpile-only for speed; run `tsc --noEmit` separately in CI.

## 💡 Examples [#-examples]

**ts-jest preset:**

```shellscript
npm i -D ts-jest typescript @types/jest
npx ts-jest config:init
```

```js
// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  roots: ['<rootDir>/src'],
};
```

**SWC:**

```js
transform: {
  '^.+\\.(t|j)sx?$': ['@swc/jest', {
    jsc: { parser: { syntax: 'typescript', tsx: true } },
  }],
},
```

**Globals import (ESM-friendly):**

```ts
import { describe, expect, test } from '@jest/globals';

test('typed', () => {
  const n: number = 1;
  expect(n).toBe(1);
});
```

**Path aliases:** mirror `paths` from `tsconfig` in `moduleNameMapper`.

## ⚠️ Pitfalls [#️-pitfalls]

* Type errors only caught if `ts-jest` diagnostics enabled — don't assume.
* JSX runtime mismatches (`react` vs `react-jsx`).
* Mixing ESM `ts-jest` experimental mode without Node flags.
* Duplicate `@types/jest` vs Vitest types in the same project.
* Compiling tests into `dist` accidentally via broad `include`.

## 🔗 Related [#-related]

* [Install](/docs/jest/install)
* [Config](/docs/jest/config)
* [React Testing Library](/docs/jest/react-testing-library)
* [Module mocks](/docs/jest/module-mocks)
* [Migration to Vitest](/docs/jest/migration-vitest)
* [Matchers](/docs/jest/matchers)


---

# Watch Mode (/docs/jest/watch-mode)



# Watch Mode [#watch-mode]

*Jest · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`jest --watch` / `--watchAll` re-runs tests on file changes. Interactive filters focus on failed tests, filenames, and related source files — ideal for TDD.

## 🔧 Core concepts [#-core-concepts]

| Mode             | Behavior                 |
| ---------------- | ------------------------ |
| `--watch`        | Git-aware changed files  |
| `--watchAll`     | All tests on any change  |
| Interactive keys | Filter, update snapshots |
| `--onlyChanged`  | Non-interactive changed  |

Requires a git/hg repo for `--watch` heuristics; else use `--watchAll`.

## 💡 Examples [#-examples]

**Scripts:**

```json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:watchAll": "jest --watchAll"
  }
}
```

**Interactive keys (typical):**

```plaintext
a  run all tests
f  run only failed
o  only changed (watch)
p  filter by filename regex
t  filter by test name regex
u  update snapshots
q  quit
```

**CLI filters without UI:**

```shellscript
npx jest --watch --testPathPattern=Button
npx jest -t "submits form" --watchAll
```

**CI:** never use watch — use `--ci`.

## ⚠️ Pitfalls [#️-pitfalls]

* `--watch` outside git showing confusing empty sets — use `--watchAll`.
* Updating snapshots with `u` without reviewing.
* Watching huge monorepos without `roots` / projects — slow.
* Editors saving continuously causing thrash — debounce/save properly.
* Relying on watch caches after dependency upgrades — restart.

## 🔗 Related [#-related]

* [Install](/docs/jest/install)
* [Snapshots](/docs/jest/snapshots)
* [Config](/docs/jest/config)
* [Coverage](/docs/jest/coverage)
* [Setup & teardown](/docs/jest/setup-teardown)
* [Matchers](/docs/jest/matchers)

