Mock的核心目标是隔离依赖、控制输入、验证行为;它通过替换真实请求、第三方库、全局状态等不稳定性因素,确保测试专注组件逻辑、可预期、可重复。

Vue 组件测试中,Mock 数据的核心目标是隔离依赖、控制输入、验证行为——不是为了“造数据”,而是为了让测试专注在组件逻辑本身。
为什么必须 Mock?
真实请求、第三方库、全局状态、时间或随机值,都会让测试变得不稳定、变慢或不可控。比如:
- 调用
axios.get('/api/user')会真正发网络请求,失败就断测试 - 组件内部用了
new Date(),不同时间跑结果可能不一致 - 引入了
lodash.throttle,测试时无法确认它是否被正确包装
常用 Mock 手段与写法
在 Vue + Vitest 环境下(当前主流组合),推荐以下三类方式:
-
Mock 函数(vi.fn):适合替换无副作用的工具函数或回调。例如把
handleClick替换成记录调用次数和参数的模拟函数,再断言它是否被触发、传了什么 -
Mock 模块(vi.mock):用于替换整个模块,如 mock
axios,让它返回固定响应,而不走真实 HTTP。可配合mockResolvedValue控制 Promise 结果 -
Mock 全局对象或 API(vi.stubGlobal):比如 stub
Date.now返回固定时间戳,或 mocklocalStorage.getItem返回预设值
实战建议:避免常见坑
Mock 不是越多越好,关键在“恰到好处”:
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
立即学习“前端免费学习笔记(深入)”;
- 只 mock 组件直接依赖的部分,不要层层 mock 子组件(该用
shallowMount或mount的global.stubs控制) - mock 后记得
vi.clearAllMocks()或使用beforeEach重置,防止测试间污染 - 对异步逻辑(如 loading 状态切换),确保 await
nextTick()或flushPromises()再做断言 - 别 mock 掉你要测的行为本身——比如测试表单校验,就别 mock 校验函数,而应 mock 输入事件和初始值
一个轻量示例(Vitest + Vue Test Utils)
假设组件内调用 api.fetchUser(id):
vi.mock('@/api', () => ({
fetchUser: vi.fn().mockResolvedValue({ id: 1, name: 'Alice' })
}))
test('显示用户姓名', async () => {
const wrapper = mount(UserProfile, { props: { userId: 1 } })
await nextTick()
expect(wrapper.find('.name').text()).toBe('Alice')
expect(fetchUser).toHaveBeenCalledWith(1)
})
Mock 数据不是绕过问题,而是把不确定性收口,让每一次测试都可预期、可重复、可信任。

















