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

如何在Jest中模拟另一个Hook内部调用的自定义Hook?

解决自定义Hook测试中mock内部Hook不生效的问题

问题根源

你的mock没生效主要有两个原因:

  • jest.mock 的位置错误:它写在了 renderHook 之后,而 renderHook 在 describe 顶层执行时,useCopySystem 已经导入并使用了原有的 useBackdrop,mock 没来得及生效。
  • renderHook 放在了 describe 顶层:describe 块内的代码会在所有测试用例执行前运行,此时mock还未正确应用,导致hook使用了未被mock的依赖。

修复步骤

  1. 将 jest.mock 移到模块最顶部:jest.mock 会被 Jest 自动提升到模块作用域的最顶端,确保在导入 useCopySystem 之前就完成mock。
  2. 把 renderHook 移到测试用例(it)内部:确保每次测试时,hook都是在mock生效后才被渲染。
  3. 确保mock的返回值符合预期:根据你的需求,让 showBackdrop 返回 true。

修正后的代码示例

// 把mock放在模块最顶部,确保在导入useCopySystem前执行
jest.mock('../utilities/useBackdrop', () => ({
  __esModule: true,
  useBackdrop: jest.fn(() => ({
    showBackdrop: jest.fn(() => true),
  })),
}));

import { renderHook } from '@testing-library/react';
import { Provider } from 'react-redux';
import configureStore from '@reduxjs/toolkit/configureStore';
import authReducer from '../path-to-auth-reducer';
import globalReducer from '../path-to-global-reducer';
import miscReducer from '../path-to-misc-reducer';
import useCopySystem from '../path-to-useCopySystem';

const createTestStore = () =>
  configureStore({
    reducer: {
      auth: authReducer,
      global: globalReducer,
      misc: miscReducer,
    },
  });

// Wrapper
const wrapper = ({ children }) => <Provider store={createTestStore()}>{children}</Provider>;

describe('test copy system', () => {
  it('pasteCopiedDay', async () => {
    // 在测试用例内部渲染hook,确保mock已生效
    const { result } = renderHook(() => useCopySystem(), { wrapper });
    const { pasteCopiedDay } = result.current;

    await pasteCopiedDay('day3Id', mockedCopyDayType);
    
    // 可选:添加断言验证mock是否被正确调用
    const { useBackdrop } = require('../utilities/useBackdrop');
    expect(useBackdrop).toHaveBeenCalled();
    expect(useBackdrop().showBackdrop).toHaveBeenCalled();
  });
});

额外注意点

  • 如果需要在不同测试用例中mock不同的返回值,可以在 it 块内使用 jest.mocked(useBackdrop).mockReturnValue(...) 来动态修改mock返回值。
  • 确保 wrapper 中的store是每次测试都重新创建的,避免测试之间的状态污染(上面的代码已经把 createTestStore() 放在了wrapper内部,每次渲染都会生成新store)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:33:21