jest.mock() 是 Jest 模拟模块的核心 API,支持自动模拟(生成空函数)、手动模拟(自定义工厂函数)和 __mocks__/ 目录集中模拟三种方式,须在 import 前调用。

jest.mock() 是 Jest 提供的核心 API,用于模拟(mock)整个模块,尤其适合第三方库(如 axios、lodash、react-router-dom 等),避免真实调用、控制返回值、隔离测试边界。
自动模拟(auto-mocking):无需实现,Jest 自动生成空函数
调用 jest.mock('module-name') 且不传第二个参数时,Jest 会自动创建一个“空壳”模拟模块:所有导出(默认 + 命名)都变成 mock 函数(jest.fn()),返回 undefined 或空对象,不执行原始代码。
- 适用于只需断言“是否被调用”,不关心返回值的场景
- 对 ESM 模块(如 React 组件、工具函数)也生效,但注意自动模拟的命名导出默认返回
undefined - 必须在模块导入前调用(通常放在文件顶部,
import之前)
示例:
// utils.js
export const fetchUser = () => Promise.resolve({ id: 1, name: 'Alice' });
// test.js
jest.mock('./utils'); // 自动模拟
import { fetchUser } from './utils';
test('fetchUser 被调用', () => {
fetchUser();
expect(fetchUser).toHaveBeenCalledTimes(1);
});
手动模拟(manual mock):提供自定义实现或返回值
传入工厂函数(factory function)作为第二个参数,可完全控制模块行为:
- 返回任意对象(覆盖默认导出和命名导出)
- 返回一个函数(适配默认导出为函数的模块,如
axios) - 内部可使用
jest.fn()记录调用、设置返回值或抛错
示例(模拟 axios):
jest.mock('axios', () => ({
get: jest.fn(),
post: jest.fn()
}));
import axios from 'axios';
test('调用 axios.get 获取用户', async () => {
axios.get.mockResolvedValue({ data: { id: 1 } });
await myApi.getUser();
expect(axios.get).toHaveBeenCalledWith('/api/user');
});
模拟 Node.js 内置模块或特定路径(如 __mocks__)
对第三方包(如 fs、path)或 npm 包,推荐在项目根目录下建 __mocks__/ 文件夹,放同名 mock 文件:
-
__mocks__/axios.js→ 自动被jest.mock('axios')使用 -
__mocks__/fs.js→ 模拟fs模块 - 该方式更集中、可复用,且无需在每个 test 文件里重复写 factory
__mocks__/axios.js 示例:
const axios = jest.requireActual('axios'); // 可选:基于真实模块增强
export default {
...axios,
get: jest.fn(),
post: jest.fn()
};
注意事项与常见陷阱
-
jest.mock()是 hoisted(提升)的,必须写在import之前,否则无效 - ESM 中模拟默认导出需注意:若原模块是
export default fn,mock 返回对象时需设default: fn - 想在某个 test 中临时取消 mock?用
jest.unmock('module')或jest.resetModules()配合require - 模拟 React 组件时,常用
jest.mock('react-router-dom', () => ({ useParams: jest.fn() }))
掌握这三种用法,就能灵活控制第三方依赖的行为,让单元测试真正聚焦于被测逻辑本身。











