PramodDutta/qaskills/seed-skills/jest-mocking-patterns/SKILL.md
Jest Mocking Patterns
Teaches the agent the right way to mock in Jest — jest.fn, mockImplementation, mockResolvedValue, jest.mock factories, spyOn with restore, and isolating modules like axios.
- Source repository stars
- 211
- Declared platforms
- 4
- Static risk flags
- 1
- Last source update
- 2026-08-28
- Source checked
- 2026-08-28
Decision brief
What it does: where it fits
This skill makes the agent mock dependencies in Jest deliberately and reversibly: stubbing functions with jest.fn, controlling return values with mockReturnValue/mockResolvedValue, replacing whole modules with jest.mock factories, and spying on real implementations with jest.spy…
Not for
- Mocking the function under test. The test then verifies the mock, not the code. Mock the dependency it calls.
- No clearAllMocks/clearMocks. Call counts and implementations bleed across tests, producing order-dependent flakiness.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Declared | Source record | Install path and trigger |
| Claude Code | Declared | Source record | Install path and trigger |
| Cursor | Declared | Source record | Install path and trigger |
| Gemini CLI | Declared | Source record | Install path and trigger |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/PramodDutta/qaskills --skill "seed-skills/jest-mocking-patterns"Inspect the Agent Skill "Jest Mocking Patterns" from https://github.com/PramodDutta/qaskills/blob/fb3fbec70591bad971dd97c5d9add6eaa99bae18/seed-skills/jest-mocking-patterns/SKILL.md at commit fb3fbec70591bad971dd97c5d9add6eaa99bae18. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Workflow / Patterns
jest.fn() is a recording stub. Drive it with mockReturnValue, mockResolvedValue, mockRejectedValue, or queue per-call values with mockReturnValueOnce.
jest.fn() is a recording stub. Drive it with mockReturnValue, mockResolvedValue, mockRejectedValue, or queue per-call values with mockReturnValueOnce.When the return depends on the input, supply a function. Use mockImplementationOnce for sequenced behavior.jest.mock replaces an entire module. Because it is hoisted above imports, any variable the factory references must be named with a mock prefix. - 02
Core Principles
1. Mock at the boundary. Mock network/DB/3rd-party clients, not the function you are testing. If you mock the thing under test, the test proves nothing. 2. Reset mocks between tests. Configure clearMocks: true (or call jest.clearAllMocks() in beforeEach) so call counts and imple…
Mock at the boundary. Mock network/DB/3rd-party clients, not the function you are testing. If you mock the thing under test, the test proves nothing.Reset mocks between tests. Configure clearMocks: true (or call jest.clearAllMocks() in beforeEach) so call counts and implementations never bleed across tests.jest.mock is hoisted. Calls to jest.mock('module', factory) are lifted above imports. The factory cannot reference outer variables unless they are prefixed mock. - 03
Pattern 1 — jest.fn and controlling return values
jest.fn() is a recording stub. Drive it with mockReturnValue, mockResolvedValue, mockRejectedValue, or queue per-call values with mockReturnValueOnce.
jest.fn() is a recording stub. Drive it with mockReturnValue, mockResolvedValue, mockRejectedValue, or queue per-call values with mockReturnValueOnce. - 04
Pattern 2 — mockImplementation for logic-bearing stubs
When the return depends on the input, supply a function. Use mockImplementationOnce for sequenced behavior.
When the return depends on the input, supply a function. Use mockImplementationOnce for sequenced behavior. - 05
Pattern 3 — jest.mock with a factory (the hoisting rule)
jest.mock replaces an entire module. Because it is hoisted above imports, any variable the factory references must be named with a mock prefix.
jest.mock replaces an entire module. Because it is hoisted above imports, any variable the factory references must be named with a mock prefix.
Permission review
Static risk signals and limitations
Network access
The documentation includes network, browsing, or remote request actions.
const { data } = await axios.get(`/api/users/${id}`);Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 92/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 211 | Source | Repository attention, not individual Skill quality |
| Compatibility | 4 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- PramodDutta/qaskills
- Skill path
- seed-skills/jest-mocking-patterns/SKILL.md
- Commit
- fb3fbec70591bad971dd97c5d9add6eaa99bae18
- License
- MIT
- Collected
- 2026-08-28
- Default branch
- main
View the original SKILL.md
Jest Mocking Patterns
This skill makes the agent mock dependencies in Jest deliberately and reversibly: stubbing functions with jest.fn, controlling return values with mockReturnValue/mockResolvedValue, replacing whole modules with jest.mock factories, and spying on real implementations with jest.spyOn (always restored). The guiding rule: mock the boundary, not the unit under test, and always reset state between tests so mocks never leak.
Use this skill when the agent needs to isolate code from the network, the clock, the filesystem, a database client, or any third-party module (axios, fs, a payment SDK).
Core Principles
- Mock at the boundary. Mock network/DB/3rd-party clients, not the function you are testing. If you mock the thing under test, the test proves nothing.
- Reset mocks between tests. Configure
clearMocks: true(or calljest.clearAllMocks()inbeforeEach) so call counts and implementations never bleed across tests. jest.mockis hoisted. Calls tojest.mock('module', factory)are lifted above imports. The factory cannot reference outer variables unless they are prefixedmock.- Prefer
spyOn+mockRestoreoverjest.mockwhen you only need to override one method and want the real implementation back afterward. - Type your mocks. Use
jest.mocked()(oras jest.Mock) so the mock API is type-checked and autocompletes. - Assert behavior, then interactions. Check the result first; use
toHaveBeenCalledWithto verify the boundary was called correctly.
Workflow / Patterns
Pattern 1 — jest.fn and controlling return values
jest.fn() is a recording stub. Drive it with mockReturnValue, mockResolvedValue, mockRejectedValue, or queue per-call values with mockReturnValueOnce.
test('jest.fn return value control', () => {
const calc = jest.fn();
calc.mockReturnValue(10); // default for every call
calc.mockReturnValueOnce(1).mockReturnValueOnce(2); // queued, then falls back
expect(calc()).toBe(1);
expect(calc()).toBe(2);
expect(calc()).toBe(10);
expect(calc).toHaveBeenCalledTimes(3);
});
test('async return values', async () => {
const fetchUser = jest.fn<Promise<{ id: number }>, [number]>();
fetchUser.mockResolvedValue({ id: 1 });
await expect(fetchUser(1)).resolves.toEqual({ id: 1 });
fetchUser.mockRejectedValueOnce(new Error('not found'));
await expect(fetchUser(99)).rejects.toThrow('not found');
});
Pattern 2 — mockImplementation for logic-bearing stubs
When the return depends on the input, supply a function. Use mockImplementationOnce for sequenced behavior.
test('mockImplementation reacts to args', () => {
const discount = jest.fn((price: number, isMember: boolean) =>
isMember ? price * 0.9 : price,
);
expect(discount(100, true)).toBe(90);
expect(discount(100, false)).toBe(100);
expect(discount).toHaveBeenLastCalledWith(100, false);
});
test('retry then succeed via mockImplementationOnce', async () => {
const send = jest
.fn<Promise<string>, []>()
.mockImplementationOnce(() => Promise.reject(new Error('503')))
.mockImplementationOnce(() => Promise.resolve('ok'));
await expect(send()).rejects.toThrow('503');
await expect(send()).resolves.toBe('ok');
});
Pattern 3 — jest.mock with a factory (the hoisting rule)
jest.mock replaces an entire module. Because it is hoisted above imports, any variable the factory references must be named with a mock prefix.
// notifier.ts
import { sendSms } from './sms-client';
export async function notify(phone: string, msg: string) {
await sendSms(phone, msg);
return `sent to ${phone}`;
}
// notifier.test.ts
import { notify } from './notifier';
import { sendSms } from './sms-client';
// Hoisted: the factory may only use `mock`-prefixed outer vars.
const mockSend = jest.fn();
jest.mock('./sms-client', () => ({
sendSms: (...args: unknown[]) => mockSend(...args),
}));
beforeEach(() => jest.clearAllMocks());
test('notify calls the SMS client correctly', async () => {
mockSend.mockResolvedValue(undefined);
const result = await notify('+15551234567', 'Hello');
expect(result).toBe('sent to +15551234567');
expect(sendSms).toHaveBeenCalledWith('+15551234567', 'Hello');
expect(sendSms).toHaveBeenCalledTimes(1);
});
Pattern 4 — jest.spyOn with restore (override one method, keep the rest)
spyOn wraps a real method so you can assert on it and optionally stub it. Always restore — restoreMocks: true in config, or mockRestore().
import * as mathUtils from './math-utils';
afterEach(() => jest.restoreAllMocks());
test('spy that still calls through', () => {
const spy = jest.spyOn(mathUtils, 'add'); // real impl runs
const sum = mathUtils.add(2, 3);
expect(sum).toBe(5);
expect(spy).toHaveBeenCalledWith(2, 3);
});
test('spy that replaces the implementation', () => {
jest.spyOn(mathUtils, 'add').mockReturnValue(42);
expect(mathUtils.add(2, 3)).toBe(42); // stubbed
// restoreAllMocks() puts the real add back after this test.
});
test('spy on Date.now for deterministic time', () => {
jest.spyOn(Date, 'now').mockReturnValue(1_700_000_000_000);
expect(Date.now()).toBe(1_700_000_000_000);
});
Pattern 5 — Mocking axios (auto-mock + typed handle)
A real-world boundary. jest.mock('axios') auto-mocks the module; jest.mocked gives a typed handle.
// user-service.ts
import axios from 'axios';
export async function getUser(id: number) {
const { data } = await axios.get(`/api/users/${id}`);
return data;
}
// user-service.test.ts
import axios from 'axios';
import { getUser } from './user-service';
jest.mock('axios');
const mockedAxios = jest.mocked(axios);
beforeEach(() => jest.clearAllMocks());
test('resolves the user from the API', async () => {
mockedAxios.get.mockResolvedValue({ data: { id: 1, name: 'Ada' } });
const user = await getUser(1);
expect(user).toEqual({ id: 1, name: 'Ada' });
expect(mockedAxios.get).toHaveBeenCalledWith('/api/users/1');
});
test('propagates a network error', async () => {
mockedAxios.get.mockRejectedValueOnce(new Error('Network Error'));
await expect(getUser(1)).rejects.toThrow('Network Error');
});
Pattern 6 — Partial module mock with requireActual
Keep most of a module real, override one export. Essential when a util module mixes pure helpers with a side-effecting one.
jest.mock('./config', () => ({
...jest.requireActual('./config'),
isProduction: jest.fn().mockReturnValue(false), // override only this
}));
Pattern 7 — Fake timers for debounce/throttle/setTimeout code
test('debounced save fires once after the delay', () => {
jest.useFakeTimers();
const save = jest.fn();
const debounced = makeDebounced(save, 300);
debounced();
debounced();
jest.advanceTimersByTime(300);
expect(save).toHaveBeenCalledTimes(1);
jest.useRealTimers();
});
Best Practices
- Set
clearMocks: trueandrestoreMocks: trueinjest.configso state never leaks between tests and spies always restore. - Prefix factory-referenced variables with
mockto satisfy Jest's hoisting rule; otherwise the factory throws a reference error. - Use
jest.mocked(x)for typed access to mocked modules instead of unsafeas anycasts. - Reach for
spyOnfirst when overriding a single method — it is reversible and keeps the rest real. - Assert the result before the interaction. Confirm the output, then
toHaveBeenCalledWithto verify how the boundary was invoked. - Use
mockResolvedValueOnce/mockRejectedValueOnceto script retry and error paths precisely. - Use fake timers for time-dependent code instead of real
setTimeoutwaits.
Anti-Patterns
- Mocking the function under test. The test then verifies the mock, not the code. Mock the dependency it calls.
- No
clearAllMocks/clearMocks. Call counts and implementations bleed across tests, producing order-dependent flakiness. - Referencing a non-
mockouter variable in ajest.mockfactory. Hoisting moves the factory above the declaration -> ReferenceError. spyOnwithout restore. The stub leaks into later tests in the same file.- Over-mocking — stubbing every collaborator until the test no longer exercises real logic. Mock only the I/O boundary.
- Asserting only
toHaveBeenCalled()without checking arguments or the actual result — weak tests that pass on wrong calls. as anyon mocked modules, discarding the type safetyjest.mockedprovides.
When to Trigger This Skill
- "Mock axios / fetch / an HTTP client in my Jest test"
- "How do I use
jest.mockwith a factory?" - "
mockResolvedValue/mockReturnValueOnce— how do these work?" - "Spy on a method but keep the real implementation"
- "My Jest mock leaks into the next test"
- "ReferenceError: cannot access X before initialization in
jest.mock" - "Mock only one export from a module" / "partial mock"
- "Test debounced / setTimeout code with fake timers"
Frequently asked questions
What to verify before installation and use
What does the Jest Mocking Patterns source document cover?
This skill makes the agent mock dependencies in Jest deliberately and reversibly: stubbing functions with jest.fn, controlling return values with mockReturnValue/mockResolvedValue, replacing whole modules with jest.mock factories, and spying on real implementations with jest.spy…
How do I install Jest Mocking Patterns?
The source record exposes this install command: npx skills add https://github.com/PramodDutta/qaskills --skill "seed-skills/jest-mocking-patterns". Inspect the command and pinned source before running it.
Which Agent platforms does the source record declare?
The pinned source record declares support for: codex, claude code, cursor, gemini cli.
Which permission-related actions were detected?
Static rules flagged network in the source; the page lists the matching lines and excerpts.
Alternatives
Compare before choosing
PramodDutta/qaskills
RAG Regression Testing
Gate RAG pipelines in CI with versioned golden eval sets, per-metric thresholds, baseline drift detection, and a build that fails when retrieval or answer quality regresses.
PramodDutta/qaskills
State Machine Test Generator
Generate comprehensive test cases from state machine models covering all states, transitions, guard conditions, and invalid transition attempts for workflow-heavy features
PramodDutta/qaskills
API Test Suite Generator
Automatically generate comprehensive API test suites from OpenAPI specifications covering CRUD operations, error handling, authentication, pagination, and edge cases
PramodDutta/qaskills
CI Pipeline Optimizer
Optimize CI test pipelines through intelligent test splitting, parallelization, caching strategies, and selective test execution based on code changes.