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

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);
  });
});

补充说明

  1. 第二种写法(测试内手动设置mockReturnValue)能生效,是因为你在测试文件中导入了barFn,Vitest此时正确绑定了Mock函数的引用,手动设置返回值后覆盖了初始状态,但这种写法需要每个测试用例重复设置,不够高效。
  2. 第三种写法(用普通函数)能通过第一个测试,但无法修改Mock,是因为普通函数不具备Vitest Mock函数的mockReturnValue等方法,仅适合不需要动态修改Mock行为的场景。

内容的提问来源于stack exchange,提问作者leanne1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:06:00