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

Vue 3组合式API中如何用vi.spyOn测试组件内函数?

问题原因及解决办法

核心问题

你用vi.spyOn(UploadFile, 'addNewImage')报错的原因是:Vue 3组合式API(<script setup>)中定义的addNewImage是组件内部私有函数,既不是组件对象的静态方法,也不会默认暴露到组件实例上,直接spy组件导出对象自然找不到这个方法。

解决办法

方法1:主动暴露函数到组件实例

在组件中用defineExpose把addNewImage暴露出来,测试时通过组件实例访问:

<!-- UploadFile.vue -->
<script setup lang="ts">
const addNewImage = async (e: Event) => {
  // 你的上传逻辑
}

// 仅为测试暴露函数
defineExpose({ addNewImage })
</script>

测试代码:

// uploadFile.spec.ts
import { mount } from '@vue/test-utils'
import UploadFile from './UploadFile.vue'

test('input change触发addNewImage', async () => {
  const wrapper = mount(UploadFile)
  // 通过wrapper.vm访问暴露的方法
  const spy = vi.spyOn(wrapper.vm, 'addNewImage')
  
  await wrapper.find('input[type="file"]').trigger('change')
  expect(spy).toHaveBeenCalled()
})

方法2:抽离逻辑为独立函数(更推荐)

把addNewImage的核心上传逻辑抽成独立工具函数,单独测试工具函数,组件测试只验证事件绑定和调用:

// utils/upload.ts
export const handleImageUpload = async (file: File) => {
  // 原addNewImage中的核心逻辑,比如文件校验、上传请求等
}

组件中调用这个工具函数:

<!-- UploadFile.vue -->
<script setup lang="ts">
import { handleImageUpload } from './utils/upload'

const addNewImage = async (e: Event) => {
  const target = e.target as HTMLInputElement
  const file = target.files?.[0]
  if (file) {
    await handleImageUpload(file)
  }
}
</script>

测试工具函数:

// utils/upload.spec.ts
import { handleImageUpload } from './upload'

test('图片上传逻辑验证', async () => {
  const mockFile = new File(['test'], 'test.jpg', { type: 'image/jpeg' })
  await handleImageUpload(mockFile)
  // 这里添加对逻辑的断言,比如是否调用了上传接口等
})

组件测试验证事件触发:

// uploadFile.spec.ts
import { mount } from '@vue/test-utils'
import UploadFile from './UploadFile.vue'
import * as uploadUtils from './utils/upload'

test('input change触发上传逻辑', async () => {
  const spy = vi.spyOn(uploadUtils, 'handleImageUpload').mockResolvedValue()
  const wrapper = mount(UploadFile)
  
  const mockFile = new File(['test'], 'test.jpg', { type: 'image/jpeg' })
  await wrapper.find('input[type="file"]').trigger('change', {
    target: { files: [mockFile] }
  })
  
  expect(spy).toHaveBeenCalledWith(mockFile)
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:42:14