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这个文件导出的,按照下面的步骤写:
- 先导入整个模块和目标Hook:
import * as usePodcasterDataModule from '../hooks/usePodcasterData'; import { usePodcasterData } from '../hooks/usePodcasterData';
- 用
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
相关产品推荐
相关产品推荐

