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

如何在Vitest中测试Vue3 Watch触发的函数?

解决Vue3组件中Vitest测试watch触发的问题

问题根源

你在<script setup>中声明的page、doCaseSearch都是组件内部私有成员,默认不会挂载到组件实例(wrapper.vm)上,所以直接通过wrapper.vm.page修改值或者监听wrapper.vm.doCaseSearch都会失效。

正确实现方法

方法1:通过defineExpose暴露测试所需的成员

先修改组件代码,把需要测试的变量和函数暴露给外部:

<script setup>
import { ref, watch } from 'vue'

const page = ref(1)
const size = ref(25)
const sort = ref(new Array<Order>()) // 修正原代码语法错误:移除多余的>
const searchProps = ref(/* 你的初始值 */)

const doCaseSearch = (props) => {
  // 你的业务逻辑实现
}

watch([page, size, sort], () => doCaseSearch(searchProps.value))

// 暴露给测试用例
defineExpose({
  page,
  doCaseSearch,
  searchProps // 如需验证传参可一并暴露
})
</script>

然后编写测试用例:

import { mount, flushPromises } from '@vue/test-utils'
import { vi } from 'vitest'
import YourComponent from './YourComponent.vue'

it('should call doCaseSearch when page changes', async () => {
  const wrapper = mount(YourComponent)
  // 获取暴露的成员
  const { page } = wrapper.vm
  // 创建函数 spy
  const doCaseSearchSpy = vi.spyOn(wrapper.vm, 'doCaseSearch')

  // 修改响应式变量的值
  page.value = 7
  // 等待watch回调及响应式更新完成
  await flushPromises()

  // 断言函数调用次数
  expect(doCaseSearchSpy).toHaveBeenCalledTimes(1)
  // 可选:验证传入参数是否正确
  // expect(doCaseSearchSpy).toHaveBeenCalledWith(wrapper.vm.searchProps.value)
})

方法2:模拟用户交互触发page变化(无需修改组件)

如果不想暴露组件内部成员,可以通过模拟用户操作触发page变化。假设组件内有分页按钮,点击对应按钮会修改page值:

it('should call doCaseSearch when page changes via user interaction', async () => {
  const wrapper = mount(YourComponent)
  // 假设分页按钮的选择器为`.pagination-btn[data-page="7"]`
  await wrapper.find('.pagination-btn[data-page="7"]').trigger('click')
  await flushPromises()

  // 可通过断言组件状态变化或外部依赖调用情况验证逻辑,比如mock接口后断言调用
})

补充说明

  • 原组件代码中const sort = ref(new Array<Order>()>存在语法错误,需修正为const sort = ref(new Array<Order>())。
  • flushPromises()用于等待watch回调(若含异步逻辑)和响应式更新完成,确保断言时机正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:23:24