如何用Jest模拟带多级路径导入的@SomeOrg/SomeLibrary模块
Jest 通用模拟多级路径导入的 Node 模块方法
问题原因
你之前的 mock 方式只针对模块根路径 @SomeOrg/SomeLibrary 生效,但代码中导入的是子路径模块(如 @SomeOrg/SomeLibrary/Module1),Jest 会将这些子路径视为独立模块,因此根路径的 mock 无法覆盖它们。
方法一:使用 __mocks__ 目录 + moduleNameMapper(推荐,结构清晰)
这种方式通过映射模块路径到自定义 mock 文件,完美适配所有子路径导入:
- 创建对应模块结构的 mock 目录
在项目根目录下建立如下目录结构:
__mocks__/ @SomeOrg/ SomeLibrary/ Module1/ SubModule.js Module1.js Module2.js
- 编写各子模块的 mock 文件
__mocks__/@SomeOrg/SomeLibrary/Module1.js:
export const SOME_IMPORTS_FROM_MODULE1 = jest.fn(); // 导出子模块,支持从 Module1 导入 SubModule 的场景 export * from './SubModule';
__mocks__/@SomeOrg/SomeLibrary/Module1/SubModule.js:
export const SOME_IMPORTS_FROM_SUB_MODULE = jest.fn();
__mocks__/@SomeOrg/SomeLibrary/Module2.js:
export const SOME_IMPORTS_FROM_MODULE2 = jest.fn();
- 配置 Jest 路径映射
在jest.config.js中添加moduleNameMapper,将原模块的所有子路径映射到 mock 目录:
module.exports = { // 其他 Jest 配置... moduleNameMapper: { '^@SomeOrg/SomeLibrary/(.*)$': '<rootDir>/__mocks__/@SomeOrg/SomeLibrary/$1' } };
方法二:动态通配符 mock(适合快速统一处理)
如果不想创建大量 mock 文件,可以用 Jest 的正则匹配结合动态 mock 逻辑,一次性覆盖所有子路径:
在 Jest 的 setupFiles 配置文件中添加如下代码:
// 匹配所有 @SomeOrg/SomeLibrary 开头的子路径模块 jest.mock(/^@SomeOrg\/SomeLibrary\/.*/, () => { // 用 Proxy 动态生成所有导出的 mock 函数 return new Proxy({}, { get(target, prop) { // 标识为 ES 模块,避免导入报错 if (prop === '__esModule') return true; // 所有导出属性都返回 jest 模拟函数 return jest.fn(); }, // 支持枚举导出属性 ownKeys() { // 根据你的实际导出调整,比如返回所有用到的导出名 return ['SOME_IMPORTS_FROM_MODULE1', 'SOME_IMPORTS_FROM_SUB_MODULE', 'SOME_IMPORTS_FROM_MODULE2']; }, getOwnPropertyDescriptor(target, prop) { return { enumerable: true, configurable: true, value: jest.fn() }; } }); });
这种方式会为所有子路径模块的导出属性自动生成 mock 函数,适合导出以函数为主的场景。
内容的提问来源于stack exchange,提问作者Gavara.Suneel
相关产品推荐
相关产品推荐

