Vue3 Script Setup中如何用Vitest测试onMounted内方法调用
在Vue3 Script Setup中用Vitest测试onMounted调用指定方法的方案
针对Script Setup下无法在挂载前监视内部方法、进而无法验证onMounted调用的问题,提供两种可行解决方案:
方案1:将目标方法抽离到外部模块(推荐)
把methodTest单独提取到工具模块,可直接在测试中mock并监视调用:
步骤1:重构组件代码
新建工具文件utils.js:
export const methodTest = async () => { await ... // 原方法逻辑 };
修改组件,导入并使用该方法:
<script setup> import { onMounted } from 'vue'; import { methodTest } from './utils'; onMounted(() => { methodTest(); }); defineExpose({ methodTest }); </script> <template> <div>Component</div> </template>
步骤2:编写测试代码
import { mount } from '@vue/test-utils'; import MyComponent from './MyComponent.vue'; import * as utils from './utils'; test('onMounted钩子调用了methodTest', async () => { // 创建spy并mock方法实现 const methodTestSpy = vi.spyOn(utils, 'methodTest').mockResolvedValue(); // 挂载组件 mount(MyComponent); // 验证方法是否被调用 expect(methodTestSpy).toHaveBeenCalled(); // 恢复原方法,避免影响其他测试 methodTestSpy.mockRestore(); });
方案2:通过依赖注入替换方法(无需抽离模块)
若不想调整组件结构,可利用Vue的依赖注入机制,在测试时替换目标方法为spy:
步骤1:修改组件代码
<script setup> import { inject, onMounted } from 'vue'; // 优先使用注入的方法,不存在则使用默认实现 const methodTest = inject('methodTest', async () => { await ... // 原方法逻辑 }); onMounted(() => { methodTest(); }); defineExpose({ methodTest }); </script> <template> <div>Component</div> </template>
步骤2:编写测试代码
import { mount } from '@vue/test-utils'; import MyComponent from './MyComponent.vue'; test('onMounted钩子调用了methodTest', async () => { // 创建spy方法 const methodTestSpy = vi.fn().mockResolvedValue(); // 挂载组件时注入spy mount(MyComponent, { global: { provide: { methodTest: methodTestSpy } } }); // 验证调用 expect(methodTestSpy).toHaveBeenCalled(); });
两种方案均可解决挂载后无法监视方法的问题,方案1更符合模块化设计思想,方案2适合不想调整组件结构的场景。
内容的提问来源于stack exchange,提问作者Deivis Rodriguez
相关产品推荐
相关产品推荐

