使用Vitest模拟useMutation时,让mock的mutateAsync触发真实onSuccess
解决Vitest中Mock useUpload Hook时触发onSuccess的问题
你的问题出在当前的mock只模拟了mutateAsync方法,但完全忽略了原useUpload中触发onSuccess的逻辑——原Hook里mutateAsync执行完成后,会通过react-query的useMutation回调触发传入的onSuccess,而你的mock没有实现这个环节。
要同时满足验证调用参数和触发onSuccess的需求,可以修改mock逻辑,让它接收并处理传入的onSuccess参数,在mutateAsync执行完成后手动调用该回调:
import type { UseUploadProps } from 'hooks/useUpload.tsx'; // 定义mock的mutateAsync,用于后续验证调用参数 const mockedMutateAsync = vi.fn(async () => { // 可根据需求添加模拟的返回值,比如后端返回的文件信息 }); vi.mock('hooks/useUpload.tsx', () => ({ useUpload: ({ onSuccess }: UseUploadProps = {}) => { // 包装mock的mutateAsync,在执行完成后触发onSuccess const wrappedMutate = async (...args: Parameters<typeof mockedMutateAsync>) => { const result = await mockedMutateAsync(...args); // 调用传入的onSuccess回调 onSuccess?.(); return result; }; return { mutateAsync: wrappedMutate, // 如果测试中需要用到isLoading等其他属性,可在这里模拟 isLoading: false, }; }, }));
之后你依然可以正常验证调用参数:
expect(mockedMutateAsync).toHaveBeenCalledWith({ test: '123' });
这样修改后,当组件调用mutateAsync完成时,mock逻辑会自动触发传入的onSuccess,成功界面就能正常展示,同时也不影响你对调用参数的验证。
内容的提问来源于stack exchange,提问作者Daniel Barbakadze
相关产品推荐
相关产品推荐

