首页 > 解决方案 > 为什么我在测试这个钩子时会看到关于使用 act 的警告?

问题描述

使用“@testing-library/react-hooks”中的 renderHook 时,我无法理解如何在没有以下警告的情况下为钩子编写测试。

“警告:测试中对 TestHook 的更新未包含在 act(...) 中。”

基本上,钩子使用设置初始值,useState然后在useEffect钩子中我异步执行一些操作,最终更新状态值。

import React from "react";

// fake request
const fetchData = () => Promise.resolve("data");

export const useGetData = () => {
  const initialData = { state: "loading" };
  const [data, setData] = React.useState(initialData);

  React.useEffect(() => {
    fetchData()
      .then(() => setData({ state: "loaded" }));
  }, []);

  return data;
};

钩子总是简单地返回状态值。所以我写了一个测试来断言它首先返回初始值并最终返回新的状态值。

import { renderHook } from "@testing-library/react-hooks";
import { useGetData } from "./useGetData";

describe("useGetData", async () => {
  it('Should initially return an object with state as "loading"', () => {
    const { result } = renderHook(() => useGetData());
    expect(result.current).toEqual({ state: "loading" });
  });

  it('Should eventually return an object with state as "loaded"', async () => {
    const { result, waitForNextUpdate } = renderHook(() => useGetData());
    await waitForNextUpdate();
    expect(result.current).toEqual({ state: "loaded" });
  });
});

我创建了一个复制此的沙箱: https ://codesandbox.io/s/dazzling-faraday-ht4cd?file=/src/useGetData.test.ts

我已经研究了这个警告的含义和行为是什么......但对于这个特定的场景,我不确定缺少什么。

标签: reactjsjestjsreact-hooks-testing-library

解决方案


您可以通过以下方式修复它:

await act(async () => {
  await waitForNextUpdate();
});

您需要包装任何将通过该函数更新状态的act函数


推荐阅读