测试中Mock全局fetch返回undefined,如何修复该问题?
问题修复方案
核心问题分析
你遇到的报错本质是fetch mock的写法错误,导致fetch调用后返回undefined,而非预期的Promise对象,进而使得result的值为undefined,调用result.json()时触发报错(你看到的“result变量未定义”应该是报错信息的误解,实际是无法读取undefined的json属性)。
具体修复步骤
1. 修正Fetch Mock的写法
你的测试代码中,jest.fn的回调函数后面多了一个多余的逗号,导致整个mock函数返回undefined。去掉多余逗号即可:
global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve({ test: "hello world" }), }) ) as jest.Mock;
更推荐使用jest.spyOn来覆盖全局fetch,这样可以在测试后自动恢复原方法,避免影响其他测试:
beforeEach(() => { // 覆盖全局fetch,模拟成功响应 jest.spyOn(global, 'fetch').mockResolvedValue({ json: jest.fn().mockResolvedValue({ test: "hello world" }) } as unknown as Response); }); afterEach(() => { // 恢复原fetch方法 jest.restoreAllMocks(); });
2. 测试用例等待异步操作完成
组件中的数据请求是异步执行的,测试时需要等待请求完成,否则可能出现断言时机不对的问题。可以使用RTL的waitFor或异步查询方法:
it('should render AAA Component', async () => { render(<AAA />); // 等待fetch被调用,确认请求已触发 await waitFor(() => { expect(global.fetch).toHaveBeenCalledWith("https://pokeapi.co/api/v2/pokemon?limit=151"); }); // 如果组件会渲染返回的数据,可添加断言验证 // expect(screen.getByText('hello world')).toBeInTheDocument(); });
3. 组件代码添加防御性判断(可选)
为了避免类似问题在生产环境出现,可以在组件中增加对result的有效性判断:
const getData = async () => { let result; try { result = await fetch("https://pokeapi.co/api/v2/pokemon?limit=151"); // 新增:判断响应是否有效 if (!result || !result.ok) { throw new Error('请求失败或无响应'); } const data = await result.json(); setData(data); } catch (error) { console.log(error); } }
内容的提问来源于stack exchange,提问作者user1189352
相关产品推荐
相关产品推荐

