vi.mock 是 vitest 中用于局部模块模拟的 api,必须在顶层调用,支持按需覆盖导出、混合导出模拟及通过 vi.unmock 等清理策略管理 mock 状态。

vi.mock 是 Vitest 提供的模块模拟 API,用于在测试中局部替换(即“打桩”)指定模块的导出,**不影响其他测试文件或同一文件中未被 mock 的部分**。它不是全局替换,而是作用于当前测试文件(或 describe 块内),且需配合 vi.unmock 或重置策略谨慎使用。
必须在顶层调用,且不能在条件逻辑中
和 Jest 的 jest.mock 类似,vi.mock 必须出现在测试文件的最外层作用域(即 module scope),不能包裹在 test、describe 或 if 语句里,否则会被忽略或报错:
test('should call api', () => {
vi.mock('./api'); // ❌ 运行时无效,Vitest 会警告
});
✔ 正确写法:
// ✅ 顶层调用,Vitest 在编译阶段静态分析并注入 mock
vi.mock('./utils', () => ({
formatName: (name) => `Mocked: ${name}`,
DEFAULT_LANG: 'zh-CN',
}));
<p>import { formatName, DEFAULT_LANG } from './utils';</p><p>test('uses mocked formatName', () => {
expect(formatName('alice')).toBe('Mocked: alice');
expect(DEFAULT_LANG).toBe('zh-CN');
});</p>
按需 mock 部分导出(推荐:factory 函数 + 实际导入)
若只想替换某个函数,保留其余导出,可先 import 原模块,再在 factory 中选择性覆盖:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
import { getTimestamp, log } from './helpers';
<p>// 只 mock getTimestamp,log 仍为真实实现
vi.mock('./helpers', async (importOriginal) => {
const actual = await importOriginal();
return {
...actual, // 保留所有原有导出
getTimestamp: () => 1234567890, // 仅覆盖这一项
};
});</p><p>test('getTimestamp is mocked', () => {
expect(getTimestamp()).toBe(1234567890);
expect(log('test')).toBeUndefined(); // log 仍是真实函数(假设它不依赖 getTimestamp)
});</p>
模拟默认导出与命名导出混合的模块
当模块同时有 export default 和 export const xxx 时,factory 返回对象需显式包含 default 字段:
// ./logger.js
export default class Logger {
log(msg) { console.log(msg); }
}
export const LEVEL = 'INFO';
<p>// 测试文件中
vi.mock('./logger', () => ({
default: class MockLogger {
log(msg) { /<em> 自定义行为 </em>/ }
},
LEVEL: 'TEST',
}));</p><p>import Logger, { LEVEL } from './logger';</p><p>test('mocks both default and named exports', () => {
const logger = new Logger();
expect(logger instanceof Logger).toBe(true); // 注意:此时构造的是 MockLogger
expect(LEVEL).toBe('TEST');
});</p>
清除 mock 并恢复原始行为(按需)
如果同一文件中多个测试需要不同行为,可用 vi.unmock 清除,或用 vi.restoreAllMocks() 重置所有 mock 状态:
-
vi.unmock('./module'):移除对该模块的 mock,后续 import 将加载真实模块 -
vi.resetAllMocks():重置所有 mock 函数的调用记录(但不还原模块本身) -
vi.restoreAllMocks():还原所有 mock 函数为原始实现(适用于vi.fn()创建的 mock)
注意:vi.mock 本身是静态声明,vi.unmock 不会撤销已发生的模块替换,它主要影响后续的 import 行为 —— 更稳妥的做法是在独立的 describe 块中隔离不同 mock 场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










