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

如何正确测试依赖useWindowSize的useSidebarWidth自定义Hook?

问题分析

你遇到的 TypeError: (0 , _hooks.useSidebarWidth) is not a function 错误,根源在于你通过 jest.mock('hooks', ...) 完全替换了整个 hooks 模块的导出,但只提供了 useWindowSize 的 mock 实现,没有保留真实的 useSidebarWidth 函数。因此测试代码中导入的 useSidebarWidth 变成了 undefined,导致调用失败。

解决方案

正确的做法是只 mock useWindowSize,同时保留 useSidebarWidth 的真实实现。可以通过 jest.requireActual 获取模块的原始导出,再覆盖需要 mock 的部分。

修正后的测试代码

import { renderHook } from '@testing-library/react-hooks';
import { useSidebarWidth, useWindowSize } from 'hooks';

// 仅 mock useWindowSize,保留其他 hook 的真实实现
jest.mock('hooks', () => ({
  ...jest.requireActual('hooks'),
  useWindowSize: jest.fn(),
}));

describe('useSidebarWidth', () => {
  // 每次测试前重置 mock,避免测试间污染
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('窗口宽度小于1440px时,返回72px作为侧边栏宽度', () => {
    // 设置 mock 返回值
    (useWindowSize as jest.Mock).mockReturnValue({ width: 700 });
    const { result } = renderHook(() => useSidebarWidth());
    
    expect(result.current.sidebarWidth).toBe('72px');
    expect(result.current.isExpanded).toBe(false);
  });

  it('窗口宽度大于1440px时,返回248px作为侧边栏宽度', () => {
    (useWindowSize as jest.Mock).mockReturnValue({ width: 1500 });
    const { result } = renderHook(() => useSidebarWidth());
    
    expect(result.current.sidebarWidth).toBe('248px');
    expect(result.current.isExpanded).toBe(true);
  });
});

关键说明

  1. jest.requireActual 的作用:获取 hooks 模块的原始导出,确保 useSidebarWidth 是真实可用的函数。
  2. mock 重置:通过 beforeEach 中的 jest.clearAllMocks() 清空 mock 的调用记录和返回值,避免不同测试用例之间的干扰。
  3. 类型断言:由于 TypeScript 无法识别 mock 后的函数类型,需要用 (useWindowSize as jest.Mock) 进行类型断言,才能调用 mockReturnValue 方法。

内容的提问来源于stack exchange,提问作者Pierre Olivier Tran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:20:18