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

使用@testing-library/react测试时无法正确mock useAsync钩子问题求助

问题原因

你的问题核心是两处使用错误共同导致的:

  1. useAsync 导入/调用方式不符合你用的 react-async-hook 库的要求,导致返回的 result 字段没有正确解析Promise,直接返回了未处理的Promise对象
  2. 组件没有判断异步加载状态,且测试断言顺序不合理,在异步未完成时就触发了渲染逻辑

解决步骤

1. 修正useAsync导入方式

react-async-hook 的默认导出才是正确的钩子函数,不要使用解构导入:

// 错误写法
// import { useAsync } from "react-async-hook";
// 正确写法
import useAsync from "react-async-hook";

2. 调整组件逻辑,增加加载状态判断

异步钩子执行过程中会有pending状态,此时返回的结果是未就绪的,需要先判断加载状态避免操作未初始化的值,同时调用异步函数时用箭头函数包裹,避免参数传递异常:

import React from "react";
import useAsync from "react-async-hook";
import { getTest } from "./TestAPI";

export default function TestPanel() {
  // 用箭头函数包裹getTest调用,增加loading状态获取
  const { result: elems, loading } = useAsync(() => getTest(), []);

  // 加载中直接返回空,避免渲染未就绪的result
  if (loading) return null;

  return (
    <div>
      {elems?.map((elem, index) => {
        // 记得给map遍历的元素加key属性避免React警告
        return <div key={index}>{elem}</div>;
      })}
    </div>
  );
}

3. 调整测试代码的断言顺序

React 18 中useEffect默认延后执行,render之后同步断言接口调用的时机太早,应该把接口调用判断放到waitFor中,等待异步逻辑执行完成后统一断言:

import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import TestPanel from "./TestPanel";
import { getTest } from "./TestAPI";

jest.mock("./TestAPI");

it("renders cards correctly", async () => {
  const testArray = ["hi there"];
  getTest.mockResolvedValueOnce(testArray);

  render(<TestPanel />);

  // 等待异步逻辑执行完成后再统一断言
  await waitFor(() => {
    expect(getTest).toHaveBeenCalledTimes(1);
    expect(getTest).toHaveBeenCalledWith();
    expect(screen.getByText("hi there")).toBeInTheDocument();
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:15:03