Vitest中vi.mock初始Mock实现设置失效问题求助
Vitest中vi.mock设置具名导出初始Mock实现不生效的问题解决
问题场景
你尝试用vi.mock为ES模块的具名导出创建带初始实现的Mock,但测试报错TypeError: Cannot destructure property 'bar' of 'barFn(...)' as it is undefined,只有在测试用例内手动设置mockReturnValue才能生效,或者用普通函数实现但无法修改Mock。
相关代码如下:
待Mock模块 bar.ts
export function barFn() { return { bar: 2, }; }
被测模块 foo.ts
import { barFn } from './bar'; export function fooFn() { const { bar } = barFn(); return bar; }
失败的写法(初始Mock实现不生效)
import { fooFn } from './foo'; vi.mock('./bar', () => ({ barFn: vi.fn(() => ({ bar: 3 })), })); // FAILS describe('test', () => { it('should return mocked bar', () => { const actual = fooFn(); expect(actual).toBe(3); }); });
问题根源
你在vi.mock的工厂函数中没有添加__esModule: true标记。Vitest对ES模块的Mock需要明确识别模块类型,缺少这个标记时,具名导出的Mock函数无法被正确处理,导致你设置的初始实现没有生效,调用barFn时返回undefined。
解决方法
在vi.mock的返回对象中添加__esModule: true,明确这是ES模块的Mock:
import { fooFn } from './foo'; vi.mock('./bar', () => ({ __esModule: true, // 关键:标记为ES模块Mock barFn: vi.fn(() => ({ bar: 3 })), })); // 现在会通过 describe('test', () => { it('should return mocked bar', () => { const actual = fooFn(); expect(actual).toBe(3); }); });
补充说明
- 第二种写法(测试内手动设置
mockReturnValue)能生效,是因为你在测试文件中导入了barFn,Vitest此时正确绑定了Mock函数的引用,手动设置返回值后覆盖了初始状态,但这种写法需要每个测试用例重复设置,不够高效。 - 第三种写法(用普通函数)能通过第一个测试,但无法修改Mock,是因为普通函数不具备Vitest Mock函数的
mockReturnValue等方法,仅适合不需要动态修改Mock行为的场景。
内容的提问来源于stack exchange,提问作者leanne1
相关产品推荐
相关产品推荐

