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.
npx skills add https://github.com/PramodDutta/qaskills --skill 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).
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.spyOn + mockRestore over jest.mock when you only need to override one method and want the real implementation back afterward.jest.mocked() (or as jest.Mock) so the mock API is type-checked and autocompletes.toHaveBeenCalledWith to verify the boundary was called correctly.jest.fn and controlling return valuesjest.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');
});
mockImplementation for logic-bearing stubsWhen 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');
});
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);
});
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);
});
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');
});
requireActualKeep 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
}));
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();
});
clearMocks: true and restoreMocks: true in jest.config so state never leaks between tests and spies always restore.mock to satisfy Jest's hoisting rule; otherwise the factory throws a reference error.jest.mocked(x) for typed access to mocked modules instead of unsafe as any casts.spyOn first when overriding a single method — it is reversible and keeps the rest real.toHaveBeenCalledWith to verify how the boundary was invoked.mockResolvedValueOnce/mockRejectedValueOnce to script retry and error paths precisely.setTimeout waits.clearAllMocks/clearMocks. Call counts and implementations bleed across tests, producing order-dependent flakiness.mock outer variable in a jest.mock factory. Hoisting moves the factory above the declaration -> ReferenceError.spyOn without restore. The stub leaks into later tests in the same file.toHaveBeenCalled() without checking arguments or the actual result — weak tests that pass on wrong calls.as any on mocked modules, discarding the type safety jest.mocked provides.jest.mock with a factory?"mockResolvedValue / mockReturnValueOnce — how do these work?"jest.mock"Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Use when implementing any feature or bugfix, before writing implementation code
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always
Expert guidance for systematic backtesting of trading strategies. Use when developing, testing, stress-testing, or validating quantitative trading strategies. Covers "beating ideas to death" methodology, parameter robustness testing, slippage modeling, bias prevention, and interpreting backtest results. Applicable when user asks about backtesting, strategy validation, robustness testing, avoiding overfitting, or systematic trading development.
Cloud laboratory platform for automated protein testing and validation. Use when designing proteins and needing experimental validation including binding assays, expression testing, thermostability measurements, enzyme activity assays, or protein sequence optimization. Also use for submitting experiments via API, tracking experiment status, downloading results, optimizing protein sequences for better expression using computational tools (NetSolP, SoluProt, SolubleMPNN, ESM), or managing protein design workflows with wet-lab validation.
This skill should be used for time series machine learning tasks including classification, regression, clustering, forecasting, anomaly detection, segmentation, and similarity search. Use when working with temporal data, sequential patterns, or time-indexed observations requiring specialized algorithms beyond standard ML approaches. Particularly suited for univariate and multivariate time series analysis with scikit-learn compatible APIs.
Take pramoddutta/jest mocking patterns from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.