如何使用Testing Library测试嵌套Hook的useEffect逻辑
解决自定义Hook测试中未触发重渲染的问题
问题出在你直接修改了现有对象的isActive属性,但React Hook的依赖对比是浅比较——你mock的useNestedHook始终返回同一个对象引用,React无法感知到isActive的变化,自然不会触发useInTestHook的重渲染和useEffect的执行。
修复方案
核心思路是让useNestedHook的mock每次返回新的对象引用,并手动触发Hook重渲染来获取更新后的值:
- 调整初始mock,把固定返回对象改成jest mock函数:
jest.mock("./hooks/useNestedHook", () => ({ useNestedHook: jest.fn(), }));
- 修改测试逻辑,用变量控制
isActive状态,每次更新后触发重渲染:
describe("useInTestHook", () => { let isActiveState: boolean; beforeEach(() => { isActiveState = false; // 每次调用useNestedHook都返回新对象,确保引用变化 (useNestedHook as jest.Mock).mockImplementation(() => ({ isActive: isActiveState, })); }); afterAll(() => { jest.resetAllMocks(); }); it("should update value to 2 when isActive becomes true", () => { const { result, rerender } = renderHook(() => useInTestHook()); // 初始状态断言 expect(result.current.value).toBe(1); // 更新isActive状态并触发重渲染 isActiveState = true; rerender(); // 验证值是否更新 expect(result.current.value).toBe(2); }); });
为什么这样有效?
- 用
mockImplementation让useNestedHook每次调用都返回新的对象,确保React能通过浅比较感知到isActive的变化; - 调用
rerender()强制useInTestHook重新执行,此时会获取到更新后的isActive值,进而触发useEffect执行,完成value的更新。
内容的提问来源于stack exchange,提问作者Mikita Melnikau
相关产品推荐
相关产品推荐

