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

如何测试使用useEffect获取数据的React组件?

如何正确测试依赖useEffect获取数据的React组件

你的测试失败有两个核心原因:

  • 同步查询过早:组件渲染后立刻调用screen.getByText("Africa"),此时useEffect里的API请求还未完成,DOM中不存在目标元素,getByText会直接抛出错误,后续的waitFor根本没有执行机会。
  • 未Mock API请求:测试会调用真实的fetchContinents接口,不仅速度慢、不稳定,还可能因网络或接口返回问题导致测试失败。

解决方案步骤

1. 使用异步查询方法替代同步查询

React Testing Library提供的findBy*系列方法,是getBy*和waitFor的组合,会自动等待元素出现,无需手动编写waitFor包裹断言。

2. Mock API请求函数

在测试中模拟fetchContinents的返回值,确保测试不依赖真实接口,同时可以精准控制返回的数据。


修改后的测试代码

import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import { ContinentsList } from "./ContinentsList";
import fetchContinents from "../../api/fetchContinents";

// Mock整个API模块
jest.mock("../../api/fetchContinents");

describe("ContinentsList", () => {
  test("Renders Africa on the page", async () => {
    // 设置mock返回值,匹配组件期望的响应结构
    fetchContinents.mockResolvedValue({
      data: {
        continents: [
          { code: "AF", name: "Africa" },
          { code: "EU", name: "Europe" }
        ]
      }
    });

    render(<ContinentsList />);
    
    // 使用findByText异步等待元素出现并断言
    const africaElement = await screen.findByText("Africa");
    expect(africaElement).toBeInTheDocument();
  });
});

额外优化建议(非必需但更规范)

组件内的useState变量名与setter函数名不匹配,建议修正:

// 原代码
const [continents, setContinent] = useState();
// 修正后
const [continents, setContinents] = useState();

这样变量名与setter名对应,更易读,避免混淆。


原测试中waitFor失效的原因

你在waitFor之前就调用了screen.getByText("Africa"),这个同步方法会立刻抛出"无法找到元素"的错误,导致测试直接失败,waitFor代码块根本没有执行机会。正确做法是把查询或断言放在waitFor内部,或者直接使用findBy*方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:31:07