Jest Mock 模式

jest.fn() — Mock 函数

const mockFn = jest.fn(); mockFn('hello'); expect(mockFn).toHaveBeenCalledWith('hello'); expect(mockFn).toHaveBeenCalledTimes(1); // 设置返回值 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); // 默认回退值 // Mock 实现 const greet = jest.fn((name) => `你好,${name}!`); // 检查调用记录 console.log(mockFn.mock.calls); // [[arg1, arg2], ...] console.log(mockFn.mock.results); // [{ type: 'return', value: ... }] // 重置 mockFn.mockClear(); // 清空调用记录 mockFn.mockReset(); // 同时移除实现 mockFn.mockRestore(); // 仅适用于 spyOn

jest.mock() — 模块 Mock

// 自动 mock 整个模块 jest.mock('./utils/api'); import { fetchUser } from './utils/api'; // fetchUser 现在是 jest.fn() // 部分 mock — 保留真实实现 jest.mock('./utils/helpers', () => ({ ...jest.requireActual('./utils/helpers'), formatDate: jest.fn(() => '2024-01-01'), })); // 工厂函数 mock(在 import 之前执行) jest.mock('axios', () => ({ default: { get: jest.fn(), post: jest.fn(), }, })); import axios from 'axios'; (axios.get as jest.Mock).mockResolvedValue({ data: { id: 1 } }); afterEach(() => { jest.clearAllMocks(); });

jest.spyOn() — 监听真实方法

import * as mathUtils from './mathUtils'; // 监听而不改变实现 const spy = jest.spyOn(mathUtils, 'add'); mathUtils.add(2, 3); expect(spy).toHaveBeenCalledWith(2, 3); // 临时覆盖实现 jest.spyOn(console, 'error').mockImplementation(() => {}); // 监听类方法 class UserService { async getUser(id: string) { /* ... */ } } const service = new UserService(); const getSpy = jest.spyOn(service, 'getUser').mockResolvedValue({ id: '1', name: 'Alice' }); afterEach(() => { jest.restoreAllMocks(); });

手动 Mock — __mocks__ 目录

// __mocks__/fs.js — Node 内置模块手动 mock const fs = jest.createMockFromModule('fs'); fs.readFileSync = jest.fn((filePath) => { if (MOCK_FILE_INFO[filePath]) return MOCK_FILE_INFO[filePath]; throw new Error(`文件未找到: ${filePath}`); }); module.exports = fs; // 本地模块:__mocks__ 放在模块旁边 // src/utils/__mocks__/database.ts export const query = jest.fn().mockResolvedValue([]); export const close = jest.fn();

定时器 Mock — Fake Timers

jest.useFakeTimers(); test('防抖在延迟后触发', () => { const callback = jest.fn(); const debounced = debounce(callback, 500); debounced(); expect(callback).not.toHaveBeenCalled(); jest.advanceTimersByTime(500); expect(callback).toHaveBeenCalledTimes(1); }); // 模拟 Date.now() jest.setSystemTime(new Date('2024-06-01')); afterEach(() => { jest.useRealTimers(); });

Mock 速查表

方法用途重置方式
jest.fn()创建独立 mock 函数mockClear / mockReset
jest.mock(module)自动 mock 整个模块jest.unmock()
jest.spyOn(obj, method)监听已有方法mockRestore
jest.useFakeTimers()控制时间相关 APIuseRealTimers()
jest.clearAllMocks()清空所有 mock 调用记录
jest.restoreAllMocks()还原所有 spyOn mock