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

如何渲染并测试接入Mock API的React组件

问题根因

你的测试无法完成组件渲染层校验,是几个写法错误导致的:

  • 导入了无关的Mock方法:你从__mocks__目录引入的fetchWeatherData是独立于组件的外部函数,手动调用它不会触发Weather组件内部的state更新。实际上组件挂载时已经通过useEffect自动执行了内部定义的请求逻辑,根本不需要在测试用例里手动触发请求。
  • waitFor使用方式错误:该API的作用是轮询执行回调直到断言通过,你把请求调用放在回调内部,会导致每次轮询都重复触发请求,极易出现测试不稳定的问题。
  • 注释掉了Mock重置逻辑:afterEach中的jest.resetAllMocks()被注释后,不同测试用例之间的Mock状态会互相污染,导致测试结果不可预期。
修正后的测试代码
import axios from 'axios';
import { render, screen } from '@testing-library/react';
import Weather from '../Weather';

jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe('天气组件API Mock测试', () => {
  afterEach(() => {
    // 每个用例跑完重置Mock状态,避免用例间污染
    jest.resetAllMocks();
  });

  test('Mock返回的天气数据可正常渲染到页面', async () => {
    // 抽离固定Mock测试数据,方便断言复用
    const mockWeather = {
      forcast: 'Sunny',
      max: 28,
      min: 17,
      description: 'Clear skys all day with a warm summber breaze ariving in the afternoon',
    };

    // 固定axios.get的返回值
    mockedAxios.get.mockResolvedValue({
      data: {
        result: {
          weather: mockWeather,
        },
      },
    });

    render(<Weather />);

    // findBy系列方法内置异步等待逻辑,等待组件渲染完成后校验字段
    expect(await screen.findByText(mockWeather.description)).toBeInTheDocument();
    expect(screen.getByText(mockWeather.forcast)).toBeInTheDocument();
    expect(screen.getByText(`Temp: ${mockWeather.min} to ${mockWeather.max}`)).toBeInTheDocument();
  });
});
关键说明
  • 只需要Mock底层的axios请求方法即可,不需要导入或调用组件内部的请求函数,组件挂载后的副作用会自动触发Mock过的请求,拿到固定返回值后自动触发重渲染。
  • 把Mock数据抽为常量后,断言直接引用常量值,避免硬编码字符串拼写错误导致测试误报,后续调整测试数据时也只需要修改一处。
  • 异步场景优先使用findBy*查询方法,比手动包裹waitFor的写法更简洁,也是React Testing Library官方推荐的最佳实践。
  • 如果需要覆盖其他天气场景(比如下雪、多云),只需要修改Mock返回的forcast字段,再等待对应文本/图标渲染即可,不需要改动测试的整体逻辑。

内容的提问来源于stack exchange,提问作者goatstash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:27:13