Jest测试script.js时fetch未定义且执行导出函数外代码问题
解决Jest测试时执行顶层fetch导致的"fetch is not defined"问题
为什么Jest会执行顶层的fetch代码?
当你在测试文件中导入sum函数时,Node.js(Jest基于Node.js运行)会完整加载整个script.js模块。模块中的顶层代码(不在任何函数内部的代码)会在模块加载时自动执行,这是ES模块和CommonJS模块的标准加载机制。浏览器环境下加载该文件时,顶层fetch同样会自动执行,只是浏览器原生支持fetch API,所以不会报错。
为什么会出现"fetch is not defined"错误?
Jest运行在Node.js环境中,而Node.js默认并未内置fetch API(Node.js 18及以上版本才提供实验性支持,更早版本完全没有),因此执行顶层fetch时会抛出未定义的错误。
解决方案
方案1:将顶层fetch移至函数内部
把fetch调用封装到一个函数中,仅在需要时手动调用,避免模块加载时自动执行:
// script.js export function sum(a, b) { return a + b; } // 封装fetch逻辑到函数 export function loadWordList() { return fetch('/word-list') .then(res => res.json()) .then(data => { // 处理词表数据的逻辑 }); }
测试时仅导入sum函数,loadWordList未被调用,fetch就不会执行。
方案2:在Jest中模拟或注入fetch实现
如果必须保留顶层fetch,可以给Jest环境添加fetch支持:
- 安装
whatwg-fetch包,它能在Node.js环境中提供浏览器兼容的fetch实现:npm install whatwg-fetch --save-dev - 在Jest配置文件(
jest.config.js)中配置初始化文件:
或者直接在测试文件顶部导入:module.exports = { setupFiles: ['whatwg-fetch'] };import 'whatwg-fetch';
如果不想发起真实网络请求,还可以用Jest模拟fetch的返回值:
// script.test.js // 全局模拟fetch global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve(['apple', 'lemon', 'grape']) }) ); import { sum } from './script'; test('sum函数能正确计算两数之和', () => { expect(sum(2, 3)).toBe(5); });
方案3:根据环境条件执行fetch
在script.js中判断当前环境是否为浏览器,仅在浏览器环境下执行顶层fetch:
// script.js export function sum(a, b) { return a + b; } // 仅在浏览器环境(存在window对象)时执行fetch if (typeof window !== 'undefined') { fetch('/word-list') .then(res => res.json()) .then(data => { // 处理数据逻辑 }); }
Jest运行在Node.js环境中,window对象不存在,因此fetch不会被执行。
内容的提问来源于stack exchange,提问作者Danf
相关产品推荐
相关产品推荐

