Jest Mock Patterns

jest.fn() โ€” Mock Functions

// Create a mock function const mockFn = jest.fn(); mockFn('hello'); expect(mockFn).toHaveBeenCalledWith('hello'); expect(mockFn).toHaveBeenCalledTimes(1); // Set return values const add = jest.fn().mockReturnValue(42); const addAsync = jest.fn().mockResolvedValue({ id: 1, name: 'Alice' }); const addOnce = jest.fn() .mockReturnValueOnce(1) .mockReturnValueOnce(2) .mockReturnValue(0); // default fallback // Mock implementation const greet = jest.fn((name) => `Hello, ${name}!`); expect(greet('World')).toBe('Hello, World!'); // Inspect calls console.log(mockFn.mock.calls); // [[arg1, arg2], ...] console.log(mockFn.mock.results); // [{ type: 'return', value: ... }] console.log(mockFn.mock.instances); // `this` for each call // Reset / restore mockFn.mockClear(); // clears calls/results mockFn.mockReset(); // also removes implementation mockFn.mockRestore(); // only works with spyOn

jest.mock() โ€” Module Mocking

// Auto-mock an entire module jest.mock('./utils/api'); import { fetchUser } from './utils/api'; // fetchUser is now jest.fn() // Partial mock โ€” keep some real implementations jest.mock('./utils/helpers', () => ({ ...jest.requireActual('./utils/helpers'), formatDate: jest.fn(() => '2024-01-01'), })); // Mock with factory (runs before imports) jest.mock('axios', () => ({ default: { get: jest.fn(), post: jest.fn(), }, })); // Inside tests import axios from 'axios'; (axios.get as jest.Mock).mockResolvedValue({ data: { id: 1 } }); const result = await fetchData('/users/1'); expect(axios.get).toHaveBeenCalledWith('/users/1'); // Reset all mocks between tests afterEach(() => { jest.clearAllMocks(); });

jest.spyOn() โ€” Spy on Real Methods

import * as mathUtils from './mathUtils'; // Spy without changing implementation const spy = jest.spyOn(mathUtils, 'add'); mathUtils.add(2, 3); expect(spy).toHaveBeenCalledWith(2, 3); // Override implementation temporarily jest.spyOn(console, 'error').mockImplementation(() => {}); // Spy on class methods class UserService { async getUser(id: string) { /* ... */ } } const service = new UserService(); const getSpy = jest.spyOn(service, 'getUser').mockResolvedValue({ id: '1', name: 'Alice' }); await service.getUser('1'); expect(getSpy).toHaveBeenCalledWith('1'); // Always restore spies afterEach(() => { jest.restoreAllMocks(); });

Manual Mocks โ€” __mocks__ Directory

// __mocks__/fs.js โ€” manual mock for Node built-in 'use strict'; const path = require('path'); const MOCK_FILE_INFO = {}; const fs = jest.createMockFromModule('fs'); fs.readFileSync = jest.fn((filePath) => { if (MOCK_FILE_INFO[filePath]) return MOCK_FILE_INFO[filePath]; throw new Error(`File not found: ${filePath}`); }); fs.__setMockFiles = (newMockFiles) => { Object.assign(MOCK_FILE_INFO, newMockFiles); }; module.exports = fs; // In your test: jest.mock('fs'); const fs = require('fs'); fs.__setMockFiles({ '/etc/config.json': '{"key":"val"}' }); // For local modules: place __mocks__ next to module // src/utils/__mocks__/database.ts export const query = jest.fn().mockResolvedValue([]); export const close = jest.fn();

Timer Mocks โ€” Fake Timers

// Enable fake timers jest.useFakeTimers(); test('debounce fires after delay', () => { const callback = jest.fn(); const debounced = debounce(callback, 500); debounced(); expect(callback).not.toHaveBeenCalled(); jest.advanceTimersByTime(500); expect(callback).toHaveBeenCalledTimes(1); }); test('setInterval ticks', () => { const tick = jest.fn(); setInterval(tick, 1000); jest.advanceTimersByTime(3500); expect(tick).toHaveBeenCalledTimes(3); }); // Run all pending timers jest.runAllTimers(); // Run only currently pending timers (not nested) jest.runOnlyPendingTimers(); // Mock Date.now() jest.setSystemTime(new Date('2024-06-01')); expect(Date.now()).toBe(new Date('2024-06-01').getTime()); // Restore real timers afterEach(() => { jest.useRealTimers(); });

Mock Cheat Sheet

MethodPurposeResets With
jest.fn()Create standalone mock functionmockClear / mockReset
jest.mock(module)Auto-mock entire modulejest.unmock()
jest.spyOn(obj, method)Spy on existing methodmockRestore
jest.useFakeTimers()Control time-based APIsuseRealTimers()
jest.clearAllMocks()Clear call history on all mocksโ€”
jest.resetAllMocks()Clear + remove implementationsโ€”
jest.restoreAllMocks()Restore all spyOn mocksโ€”