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

使用@testing-library/react-hooks测试异步React Hook时act的正确位置

解决React Hooks测试中act(...)包裹的警告问题

看起来你遇到的问题根源在于mock的异步函数没有返回Promise,导致测试里的异步流程没有被@testing-library/react-hooks正确捕获,进而触发了act警告。咱们一步步来修正:

第一步:修正API的Mock方式

你的getDay应该是一个返回Promise的异步函数,但现在你用mockReturnValue直接返回了普通对象,这会让await getDay()同步完成,状态更新的时机脱离了测试工具的act包裹范围。把它改成mockResolvedValue来返回一个Promise:

jest.mock("../api/day", () => ({
  getDay: jest.fn().mockResolvedValue({ some: "value" })
}));

第二步:简化测试代码(不需要手动包裹act)

@testing-library/react-hooks提供的renderHook和waitForNextUpdate已经内部帮你处理了act的包裹工作,所以你原来的测试逻辑其实是对的,只要修正mock就能解决警告。修正后的完整测试代码:

import { renderHook, act } from "@testing-library/react-hooks";
import { useDay } from "./day";
jest.mock("../api/day", () => ({
  getDay: jest.fn().mockResolvedValue({ some: "value" })
}));

describe.only("model/day", () => {
  it("returns data", async () => {
    const { result, waitForNextUpdate } = renderHook(() => useDay());
    await waitForNextUpdate();
    expect(result.current).toEqual({ some: "value" });
  });
});

为什么之前会触发警告?

当你用mockReturnValue返回普通对象时,await getDay()会立即执行完成,状态更新set(day)会在测试工具的act处理流程之外触发,React就会抛出那个警告。而改成mockResolvedValue后,异步流程会被正确识别,waitForNextUpdate会等待Promise resolve并完成状态更新,整个过程都被包裹在act里,警告自然就消失了。

另外,如果你真的需要手动包裹act(比如处理某些同步状态更新),正确的方式是把触发状态更新的逻辑放在act回调里,但在这个异步Hook的场景下,waitForNextUpdate已经足够处理了,不需要额外手动操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:12:58