Mock 返回值没生效的关键是运行时引用与被 Mock 对象不一致,需确保 jest.mock() 在所有 import 前、检查导出方式匹配、避免模块缓存,并验证是否调用到 Mock 函数。

Mock 函数返回值没生效,通常不是代码写错了,而是 Mock 没被正确替换、调用路径不对,或作用域/模块加载时机出了问题。重点先确认「你 Mock 的那个函数,是不是运行时真正被调用的那个」。
检查 Mock 是否作用在了正确的模块实例上
ES Module 的静态导入特性会让 Mock 失效:如果你在测试文件顶部 import { fn } from './utils',然后用 jest.mock('./utils'),但又在 mockImplementation 之前就已导入,那原始函数已被缓存,Mock 就不会覆盖它。
- 把
jest.mock()放在 所有 import 之前(包括被测模块) - 或者改用
jest.doMock('./utils')+require('./utils')动态加载,确保 Mock 生效 - 验证方式:打印
console.log(utils.fn)看是否是[MockFunction]
确认调用的是 Mock 函数,而不是原始实现
常见陷阱是:被测模块内部直接引用了另一个模块的函数,但你 Mock 的是它的导出对象,而实际调用走的是未被拦截的内部引用。
- 例如
api.js导出fetchData,service.js里import { fetchData } from './api'并调用;你 Mock 了api.js,但service.js在测试前已被加载,仍持有原始引用 - 解决:对
service.js所在测试文件,使用jest.resetModules()+jest.doMock()+ 重新require - 加一行
expect(mockFn).toBeCalled(),如果没触发,说明根本没走到 Mock 分支
留意默认导出、命名导出与解构赋值的差异
Mock 返回值不生效,有时只是因为导出方式和 Mock 方式不匹配。
立即学习“Java免费学习笔记(深入)”;
- 若原模块是
export default function foo() {...},要用jest.mock('./module', () => ({ __esModule: true, default: jest.fn() })) - 若用
jest.mock('./module', () => ({ foo: jest.fn() })),但调用方是import foo from './module',就会失败——因为默认导出没被覆盖 - 推荐统一用
jest.requireActual('./module')做基础,再覆写特定方法,避免导出错位
检查是否被自动清理或重复 Mock 覆盖
Jest 默认在每个 test 之间重置 Mock,但如果手动调用了 jest.clearAllMocks() 或 jest.restoreAllMocks(),可能清掉了你设好的返回值。
- 在
beforeEach中设置 Mock 返回值,比在test内部更稳妥 - 用
mockFn.mockReturnValueOnce(val)时,注意调用次数是否超限 - 运行测试加
--no-cache,排除缓存导致模块未更新的问题
不复杂但容易忽略——Mock 生效的关键,永远是「运行时引用的对象」和「你 Mock 的对象」是否为同一个。


















