Angular Jest测试引入共享库中的JS对象时失败,报fetch未定义错误
遇到这个问题我太熟了!看起来报错指向FormatOptionData的赋值,但根源其实是你的Jest运行环境(Node.js)里没有fetch API——而问题出在你导入的@t3a/shared-data-access库中,要么是这个库的模块顶层代码(导出FormatOptionData的文件或关联模块)在加载时执行了依赖fetch的逻辑,要么是Jest环境本身没有配置fetch支持,导致导入对象时触发了未定义的fetch调用。
下面分步骤帮你解决:
第一步:先排查共享库的核心问题
先打开@t3a/shared-data-access中导出FormatOptionData的文件,仔细检查:
- 有没有在模块顶层(也就是函数/类之外的全局代码)调用
fetch?比如是不是用fetch拉取数据后赋值给FormatOptionData? - 共享库的NgModule初始化逻辑里,有没有在
ngOnInit或模块构造函数中调用fetch?
如果发现有顶层fetch调用(比如类似下面的错误写法),这才是问题的核心——模块加载时会立刻执行顶层代码,Jest环境没有fetch就直接报错:
// ❌ 错误示例:顶层异步fetch会在导入时触发 const rawData = await fetch('/api/formats').then(res => res.json()); export const FormatOptionData: Format[] = rawData;
这种情况你需要修改共享库代码,把数据初始化改成惰性加载:
// ✅ 修改为惰性加载函数,需要时再调用 export async function getFormatOptionData(): Promise<Format[]> { const rawData = await fetch('/api/formats').then(res => res.json()); return rawData as Format[]; }
如果共享库的FormatOptionData就是你贴的纯硬编码静态数组,那问题就出在Jest环境配置上,往下看:
第二步:给Jest环境添加fetch支持
方案1:启用Node.js内置fetch(Node 18+可用)
Node.js 18及以上版本已经内置了fetch API,但Jest默认可能没启用该环境。你需要修改shared-ui的Jest配置:
在libs/web/shared/ui/jest.config.ts中添加:
export default { // 保留原有配置... testEnvironmentOptions: { customExportConditions: ['node', 'node-addons'], }, };
方案2:添加fetch polyfill(兼容低版本Node)
如果你的Node版本低于18,或者不想依赖Node内置fetch,就用polyfill补全:
- 安装依赖:
npm install whatwg-fetch --save-dev
- 在
shared-ui的源码目录下创建setup-jest.ts文件:
import 'whatwg-fetch';
- 在
jest.config.ts中引入这个setup文件:
export default { // 保留原有配置... setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'], };
第三步:验证修复
重新运行你的单测命令:
nx run shared-ui:test --testFile=exercise-input.service.spec.ts
如果共享库确实是纯静态数据,上述两种方案都能解决问题;如果共享库有顶层fetch调用,那必须先修改共享库的异步逻辑,避免模块加载时触发fetch。
备注:内容来源于stack exchange,提问作者J King

