Jest报错TypeError: fetch is not a function及测试代码求助
解决Jest测试中
TypeError: fetch is not a function的问题 嘿,我看到你在Jest测试fetch请求时碰到了这个报错,这在Node.js环境里简直是家常便饭——毕竟fetch是浏览器原生API,Node.js默认根本没有内置它!咱们一步步拆解问题、搞定它:
问题根源
首先,Jest是跑在Node.js环境中的,而Node.js直到v18版本才开始原生支持fetch(还得手动开启),所以你的测试代码调用fetch时,Node找不到这个函数,直接抛出了错误。另外你代码里global.fetch = jest.mock('../mocks/movies');这行写法也不对——jest.mock是用来模拟整个模块导出的工具,不能直接赋值给global.fetch哦。
几种靠谱的解决方案
方案1:添加fetch兼容包(最简单快速)
给Node环境补上fetch的polyfill,直接用whatwg-fetch就行:
- 先安装依赖:
npm install --save-dev whatwg-fetch
- 要么在你的测试文件最顶部引入:
import 'whatwg-fetch';
要么全局配置所有测试自动加载,在jest.config.js里加:
module.exports = { setupFiles: ['whatwg-fetch'], };
方案2:用jest-fetch-mock专门模拟fetch(适合复杂测试)
这个库能让你更灵活地控制fetch的返回值、调用次数等,适合需要精细测试的场景:
- 安装依赖:
npm install --save-dev jest-fetch-mock
- 修改你的测试代码:
import MovieApiService from 'services/MovieApiService'; import movies from '../constants/movies'; import fetchMock from 'jest-fetch-mock'; // 启用fetch模拟 fetchMock.enableMocks(); describe('MovieApiService', () => { // 每个测试前重置mock,避免互相干扰 beforeEach(() => { fetchMock.resetMocks(); }); test('if jest work correctly', () => { expect(true).toBe(true); }); test('get an array of popular movies', () => { // 设置fetch返回你预设的mock数据 fetchMock.mockResolvedValue({ json: () => Promise.resolve(movies), }); const movieApiService = new MovieApiService(); return movieApiService.getPopularMovies() .then(data => expect(data).toEqual(movies)); // 注意用toEqual而非toBe,数组是引用类型 }); });
方案3:手动全局模拟fetch(无额外依赖)
如果你不想装新库,也可以自己手动在测试里模拟fetch:
import MovieApiService from 'services/MovieApiService'; import movies from '../constants/movies'; describe('MovieApiService', () => { beforeEach(() => { // 给全局对象挂载模拟的fetch函数 global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve(movies), }) ); }); afterEach(() => { // 测试结束后清除mock,避免污染其他测试 delete global.fetch; }); test('if jest work correctly', () => { expect(true).toBe(true); }); test('get an array of popular movies', () => { const movieApiService = new MovieApiService(); return movieApiService.getPopularMovies() .then(data => expect(data).toEqual(movies)); }); });
小提醒
如果你原本想使用../mocks/movies里的mock数据,记得先import那个文件,再把它设置为fetch的返回值,而不是直接把jest.mock的结果赋值给global.fetch哦。
内容的提问来源于stack exchange,提问作者Jean
相关产品推荐
相关产品推荐

