Как подключить с помощью useEffect/setState

У меня проблемы с выполнением следующего теста:

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 | });

Я создал репро кейс в codeandbox:

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

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({});
  });
});
Другие вопросы по тегам