【问题标题】:How to hook with useEffect/setState如何与 useEffect/setState 挂钩
【发布时间】:2019-07-12 15:44:52
【问题描述】:

我无法通过以下测试:

import { useEffect, useState } from "react";

export function useComponentResources(required) {
  const [componentResources, setComponentResources] = useState(null);

  useEffect(() => {
    if (required) {
      // api call
      setTimeout(() => setComponentResources({}), 100);
    }
  }, [required]);

  return componentResources;
}
import { renderHook } from "@testing-library/react-hooks";
import { useComponentResources } from "./component-resources.hook";

describe("component-resources.hook", () => {
  it("fetches resources when required", () => {
    //act
    const { result } = renderHook(() => useComponentResources(true));

    //assert
    expect(result.current).toEqual({});
  });
});

它总是失败:

expect(received).toEqual(expected)

Expected value to equal:
  {}
Received:
  null

Difference:

  Comparing two different types of values. Expected object but received null.

   7 |     const { result } = renderHook(() => useComponentResources(true));
   9 |     //assert
> 10 |     expect(result.current).toEqual({});
  11 |   });
  12 | });

我在代码沙箱中创建了一个复制案例:

https://codesandbox.io/embed/priceless-browser-94ec2

【问题讨论】:

    标签: react-hooks-testing-library


    【解决方案1】:

    renderHook 不会等待您的setTimeout 触发;它不知道你的组件有什么“副作用”。因此,当您的 expect() 运行时,当前值仍然是其默认值 - null

    我们可以通过使用waitForNextUpdate 强制测试等到钩子再次更新,该对象位于renderHook 返回的对象上。 waitForNextUpdate 是一个函数,它返回一个承诺,一旦钩子再次更新(例如当你的 setTimeout 触发时),该承诺就会解决。

    import { renderHook } from "@testing-library/react-hooks";
    import { useComponentResources } from "./component-resources.hook";
    
    describe("component-resources.hook", () => {
      it("fetches resources when required", async () => {
        const { result, waitForNextUpdate } = renderHook(() => useComponentResources(true));
    
        await waitForNextUpdate();
    
        expect(result.current).toEqual({});
      });
    });
    

    【讨论】:

    • 您的回答完全有道理,但仍然无法使其运行。你能通过我分享的codeandbox中的测试吗?
    • 所以如果我只使用await waitForNextUpdate(),它就可以工作。如果您更新答案,我会将其标记为已接受。
    猜你喜欢
    • 2020-07-24
    • 1970-01-01
    • 2021-09-22
    • 2021-12-01
    • 2021-02-13
    • 2020-01-11
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多