如何使用Jest测试内部含useEffect且无返回值的自定义Hook多次触发逻辑
useCustomHook 测试解决方案
问题根因
- 原测试中直接修改依赖数组内对象的属性,依赖数组本身的引用未发生变化,React useEffect 依赖为浅比较,无法检测到该类变更,不会触发 effect 重执行。
- 未使用
renderHook提供的rerender方法触发 hook 重新运行,手动修改外部变量无法让测试框架感知到需要重新执行 hook 逻辑,自然不会触发更新。
正确测试代码
import { renderHook, act } from '@testing-library/react'; import { useCustomHook } from './你的hook文件路径'; describe('useCustomHook 功能验证', () => { test('挂载阶段不触发回调,仅依赖更新时执行回调', () => { const callBackMock = jest.fn(); const initialDeps = [{ dep: 'dep' }]; // 将依赖作为props传入renderHook,方便后续更新 const { rerender } = renderHook((deps) => useCustomHook(callBackMock, deps), { initialProps: initialDeps }); // 验证挂载阶段回调未执行 expect(callBackMock).toHaveBeenCalledTimes(0); // 传入新的依赖引用,触发hook重执行 act(() => { rerender([{ dep: 'foo' }]); }); // 验证依赖更新后回调执行1次 expect(callBackMock).toHaveBeenCalledTimes(1); // 可追加多次更新验证逻辑 act(() => { rerender([{ dep: 'bar' }]); }); expect(callBackMock).toHaveBeenCalledTimes(2); }); });
核心调整说明
- 将依赖项作为
renderHook的动态 props 传入,通过官方提供的rerender方法传入新的 props 触发 hook 重新运行,这是自定义 Hook 依赖变更场景的标准测试方式。 - 每次
rerender传入全新的依赖数组引用,保证 useEffect 浅比较可以识别到依赖变更,正常触发 effect 执行。 - 测试逻辑全程同步执行,无需调用
waitForNextUpdate,也不需要关注无返回值 Hook 的result.current取值,仅通过 mock 函数的调用次数即可验证功能是否符合预期。
内容的提问来源于stack exchange,提问作者Victor Cheng
相关产品推荐
相关产品推荐

