You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 07:35:27