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

Vite+React+TypeScript项目中使用Vitest mock自定义Hook时参数类型报错

Vite+React+TypeScript项目中使用Vitest mock自定义Hook时参数类型报错

我完全懂你现在的困扰!在Vitest里mock自定义Hook的时候很容易踩类型匹配的坑,尤其是和TypeScript结合的时候。先帮你梳理下问题出在哪,再给你两种可行的解决办法:

问题根源

你当前的代码里误用了vi.mock和vi.spyOn的用法:

  • vi.mock是用来mock整个模块的,第一个参数应该是模块的路径字符串,不是Hook函数本身;
  • 你想要的是监听(spy)单个Hook的调用,应该用vi.spyOn,但它的第一个参数得是包含该Hook的导出对象(比如Hook所在的模块),而不是直接传Hook函数,这就是TypeScript报类型不匹配的核心原因。
    另外还有个小细节:你的自定义Hook返回的是数组([数据, isLoading, hasError]),但你mock的时候传的是对象,这也会导致类型不兼容哦。

解决办法1:用vi.spyOn监听单个Hook

假设你的usePodcasterData Hook是从../hooks/usePodcasterData这个文件导出的,按照下面的步骤写:

  1. 先导入整个模块和目标Hook:
import * as usePodcasterDataModule from '../hooks/usePodcasterData';
import { usePodcasterData } from '../hooks/usePodcasterData';
  1. 用vi.spyOn监听Hook,并设置mock返回值:
// 从模块导出对象里监听指定的Hook
const usePodcasterDataSpy = vi.spyOn(usePodcasterDataModule, 'usePodcasterData');

// 注意要返回和Hook结构一致的数组,不是对象!
usePodcasterDataSpy.mockReturnValue([
  mockPodcastData, // 对应你的RootObject类型数据,注意可以传undefined匹配原类型
  false, // isLoading
  false  // hasError
]);

解决办法2:直接mock整个Hook所在的模块

如果不需要监听Hook的调用次数,只是想替换它的返回值,可以直接mock整个模块:

vi.mock('../hooks/usePodcasterData', () => ({
  // 直接定义mock的Hook函数,返回符合类型的数组
  usePodcasterData: vi.fn().mockReturnValue([
    mockPodcastData,
    false,
    false
  ])
}));

这样写之后,TypeScript的类型报错应该就消失了,而且mock的返回值也能和原Hook的类型完美匹配~

备注:内容来源于stack exchange,提问作者Fabricio Lancieri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 12:04:34