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

使用SWR测试模拟时waitForElementToBeRemoved超时问题求助

问题:测试依赖useSWR的异步组件时出现waitForElementToBeRemoved超时错误

运行测试时收到错误:Timed out in waitForElementToBeRemoved,组件始终停留在"Loading..."状态,无法渲染异步获取的任务列表。


问题根源分析

  1. Fetcher函数未返回Promise:SWR需要依赖fetcher返回的Promise来处理异步数据,当前代码中fetcher没有返回值,导致SWR无法完成数据加载流程。
  2. Mock数据结构与组件期望不匹配:组件中尝试遍历classAssignmentData.classInfo,但Mock接口直接返回数组,而非包含classInfo字段的对象。
  3. 测试未提供路由参数:组件通过useParams获取user和classID,但测试时未包裹路由组件,导致请求URL为http://localhost:8000/undefined/undefined/assignments,无法匹配Mock路由。
  4. 测试用例逻辑矛盾:等待"Loading..."消失后,又断言该文本存在,逻辑完全相反。

修复步骤

1. 修复Fetcher函数

确保fetcher返回Promise:

const fetcher = (...args) => {
  return fetch(...args).then((response) => response.json()); // 补充return
};

2. 修正Mock数据结构

调整Mock返回值,匹配组件期望的classInfo结构:

const server = setupServer(
  rest.get(
    "http://localhost:8000/:user/:classID/assignments",
    (req, res, ctx) => {
      return res(
        ctx.status(200),
        ctx.json({
          classInfo: [
            {
              students: "605",
              id: "605",
              firstname: "Chef",
              lastname: "Lastie",
              email: "jias",
              assignments: "asj",
              admins: "null",
            },
            {
              students: null,
              id: null,
              firstname: null,
              lastname: null,
              email: null,
              assignments: "Recess",
              admins: null,
            },
          ]
        })
      );
    }
  )
);

3. 修复测试用例的路由与逻辑

使用MemoryRouter提供路由参数,并修正断言逻辑:

import { MemoryRouter } from "react-router-dom"; // 导入路由组件

describe("AssignmentPanel", () => {
  it("displays a list of assignments", async () => {
    render(
      <MemoryRouter initialEntries={["/test-user/test-class/assignments"]}>
        <SWRConfig value={{ fetcher }}>
          <AssignmentPanel />
        </SWRConfig>
      </MemoryRouter>
    );
    
    // 等待Loading状态消失
    await waitForElementToBeRemoved(() => screen.queryByText("Loading..."));
    
    // 断言任务列表渲染成功
    expect(screen.getByText("asj")).toBeInTheDocument();
    expect(screen.getByText("Recess")).toBeInTheDocument();
    // 确认Loading文本已消失
    expect(screen.queryByText("Loading...")).not.toBeInTheDocument();
  });
});

4. (可选)优化组件的useParams类型

修正类型断言方式,避免不必要的类型转换:

type Params = {
  user: string;
  classID: string;
};
const { user, classID } = useParams<Params>()!; // 直接指定Params类型并断言非空

验证

修改完成后,测试将正常执行:组件先显示"Loading...",Mock接口返回数据后,渲染两个任务项,"Loading..."文本自动消失,断言全部通过。

内容的提问来源于stack exchange,提问作者filroy-codes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:30:42