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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 05:36:37