关键词:hooks 单测
如果你想对一个独立的 React Hook 函数进行单元测试,不涉及对它在组件中使用的测试,那么你可以使用由react-hooks-testing-library
提供的工具来完成。这个库允许你在一个隔离的环境中渲染和测试 hook 函数,而不必担心组件的其他部分。
首先,你需要安装@testing-library/react-hooks
:
npm install --save-dev @testing-library/react-hooks
或者使用 yarn:
yarn add --dev @testing-library/react-hooks
然后,让我们以一个简单的useCounter
Hook 为例,来看怎么进行单元测试。以下是这个 Hook 的代码:
import { useState, useCallback } from "react";
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = useCallback(() => setCount((c) => c + 1), []);
const decrement = useCallback(() => setCount((c) => c - 1), []);
return { count, increment, decrement };
}
export default useCounter;
接下来是对应的单元测试:
import { renderHook, act } from "@testing-library/react-hooks";
import useCounter from "./useCounter";
describe("useCounter", () => {
it("should use counter", () => {
const { result } = renderHook(() => useCounter());
expect(result.current.count).toBe(0);
});
it("should increment counter", () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
it("should decrement counter", () => {
const { result } = renderHook(() => useCounter(10));
act(() => {
result.current.decrement();
});
expect(result.current.count).toBe(9);
});
});
这里我们使用了renderHook
函数来渲染我们的 hook 并返回一个对象,这个对象中包含当前 hook 返回的所有值。我们还使用了act
函数来包裹我们对 hook 中函数的调用。这是因为 React 需要确保在测试过程中状态更新能够正常同步。
需要注意的是,如果你的 hook 依赖于其他 React 的 Context,你可以使用renderHook
的第二个参数来传入一个 wrapper,该 wrapper 是一个 React 组件,它将包裹你的 hook。
上面的这个测试覆盖了 hook 在默认值和指定初始值时的行为,以及它暴露的increment
和decrement
函数是否正常工作。这种方式可以用来测试任何自定义 hook,并且只关注 hook 本身的逻辑,不涉及到任何组件。