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

使用Jest测试带自定义Hook的组件时Mock失效该如何解决?

自定义Hook Mock失效问题解决方法

问题根本原因

你当前的写法存在两个核心错误:

  • 你将测试文件内导入的useClickAButton挂载到了本地自定义的hooks对象上再做spy,这个本地对象和组件实际引用的./hooks/index模块没有关联,mock完全不会作用到组件实际调用的hook上
  • 你调用component.container.click()是点击整个根容器,没有命中内部的button元素,所以就算hook mock成功,点击回调也不会触发

解决方案

有两种常用的实现方式,任选其一即可:

方案1:对模块命名空间做spy

直接导入整个hook模块作为命名空间对象,再对其导出的方法做spy,即可影响组件的实际引用:

// click-a-button.test.tsx
import * as React from 'react';
import {act} from "react-dom/test-utils";
import {render, screen} from "@testing-library/react";
// 导入整个hook模块作为命名空间
import * as hooks from './hooks/index'
import {ClickAButton} from "./index";

test('it runs with a mocked customHook',() =>  {
    const STATE_SPY = jest.spyOn(hooks, 'useClickAButton');
    const CLICK_HANDLER = jest.fn();

    STATE_SPY.mockReturnValue({
        handleClick: CLICK_HANDLER,
        total: 5,
    });

    render(<ClickAButton />);
    expect(screen.getByRole('button')).toHaveTextContent('5');
    act(() => {
        // 直接命中button元素触发点击
        screen.getByRole('button').click();
    });
    expect(CLICK_HANDLER).toHaveBeenCalled();
    // 测试结束清除mock,避免影响其他用例
    STATE_SPY.mockRestore();
})

方案2:使用jest.mock全局mock模块

jest的jest.mock会被自动提升到所有导入之前执行,直接替换整个模块的导出内容:

// click-a-button.test.tsx
import * as React from 'react';
import {act} from "react-dom/test-utils";
import {render, screen} from "@testing-library/react";
import {useClickAButton} from './hooks/index'
import {ClickAButton} from "./index";

// 全局mockhook模块
jest.mock('./hooks/index', () => ({
  useClickAButton: jest.fn()
}))

test('it runs with a mocked customHook',() =>  {
    const CLICK_HANDLER = jest.fn();
    // 给mock方法设置返回值
    (useClickAButton as jest.Mock).mockReturnValue({
        handleClick: CLICK_HANDLER,
        total: 5,
    });

    render(<ClickAButton />);
    expect(screen.getByRole('button')).toHaveTextContent('5');
    act(() => {
        screen.getByRole('button').click();
    });
    expect(CLICK_HANDLER).toHaveBeenCalled();
})

内容的提问来源于stack exchange,提问作者Nicholas Ladefoged

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:27:02