如何测试对 React hook 的依赖

kaj*_*acx 6 unit-testing reactjs jestjs react-hooks

我正在尝试使用测试自定义挂钩@testing-library/react-hooks,但在测试依赖项时遇到问题。让我们举useEffect个例子:

import { renderHook } from '@testing-library/react-hooks';
import { useEffect } from 'react';

test('test dependency', () => {
  const callback = jest.fn((value: number) => {});
  let currentValue = 5;

  renderHook(() => useEffect(() => callback(currentValue), [currentValue]));
  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  renderHook(() => useEffect(() => callback(currentValue), [currentValue]));
  expect(callback).toBeCalledTimes(1); // error here: called 2 times in reality
  expect(callback).toHaveBeenLastCalledWith(5);

  currentValue = 6;
  renderHook(() => useEffect(() => callback(currentValue), [currentValue]));
  expect(callback).toBeCalledTimes(2);
  expect(callback).toHaveBeenLastCalledWith(6);
});
Run Code Online (Sandbox Code Playgroud)

预期行为:useEffect不会使用相同的依赖项列表再次调用。

实际行为:useEffect每次都会被调用,可能是因为上下文被破坏并在 betweeb 之间重新创建renderHook

我还尝试将渲染方法放入一个常量中,如下所示:

const myHook = () => useEffect(() => callback(currentValue), [currentValue]);
renderHook(myHook);
Run Code Online (Sandbox Code Playgroud)

但没有运气。有什么方法可以测试依赖项列表是否正常工作?

Est*_*ask 4

预计renderHook每次调用都会挂载,执行相反的操作将阻止它与不相关的挂钩一起使用。

与 React 测试库一样render结果允许控制渲染实例,这包括unmountrerender

其他值可以像currentValue在组件中一样传递,即 props 对象。

所以它可能应该是:

  let { rerender, unmount } = renderHook(
    ({ val }) => useEffect(() => callback(val), [val]),
    { initialProps: { val: 5 } }
  );

  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  rerender({ val: 5 });

  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  rerender({ val: 6 });

  expect(callback).toBeCalledTimes(2);
  expect(callback).toHaveBeenLastCalledWith(6);
Run Code Online (Sandbox Code Playgroud)

请注意,该代码测试了 React 自己的代码useEffect,因此它没有实际用途。