You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Testing Library测试嵌套Hook的useEffect逻辑

解决自定义Hook测试中未触发重渲染的问题

问题出在你直接修改了现有对象的isActive属性,但React Hook的依赖对比是浅比较——你mock的useNestedHook始终返回同一个对象引用,React无法感知到isActive的变化,自然不会触发useInTestHook的重渲染和useEffect的执行。

修复方案

核心思路是让useNestedHook的mock每次返回新的对象引用,并手动触发Hook重渲染来获取更新后的值:

  1. 调整初始mock,把固定返回对象改成jest mock函数:
jest.mock("./hooks/useNestedHook", () => ({
  useNestedHook: jest.fn(),
}));
  1. 修改测试逻辑,用变量控制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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:22:49