我如何从 vuejs3 中的设置中监视函数?

How can I spy on a function from setup in vuejs3?

我的组件中有一个函数 setup():

export default defineComponent({
  setup() {
    const handleResume = async () => {
      msg.value = {}
      try {
      } catch (err) {
      }
    }
    return { handleResume }
  }
})

现在在我的测试中,我想创建一个像这样的间谍函数:

import App from '@/views/Frame'
jest.spyOn(App, 'handleResume')

但是我收到这个错误:

Cannot spy the handleResume property because it is not a function; undefined given instead

您必须将设置从对象切换到 return 对象的函数。所以你的设置应该是这样的:

setup() {
  const handleResume = async () => {
        msg.value = {}
        try {
          
        } catch (err) {
         
        }
      }
      
  return { handleResume }
}
     

之后你有两个选择,你可以使用@vue/test-utils,将组件作为测试文件中的包装器安装,你应该可以通过wrapper.vm.handleResume访问你的函数。其他解决方案,您可以将设置导出到可组合项并将可组合项导入测试而不是安装组件。

这需要 Vue 3.2.31 (released yesterday), which adds support for mocking Proxy methods, enabling spies on the wrapper.vm from @vue/test-utils

您可以使用 expose property from the context argumentsetup() 公开方法(或其他数据)。例如,此组件仅在测试中公开 handleResume

<!-- MyComponent.vue -->
<script>
import { defineComponent } from 'vue'

export default defineComponent({
                   
  setup(props, { expose }) {
    const handleResume = async () => true

    if (process.env.NODE_ENV === 'test') {
        
      expose({ handleResume })
    }

    return { handleResume }
  }
})
</script>

<template>
  <button @click="handleResume">Click</button>
</template>

如果您有 <script setup>,请使用 defineExpose() macro:

<!-- MyComponent.vue -->
<script setup>
const handleResume = async () => true

if (process.env.NODE_ENV === 'test') {
       
  defineExpose({ handleResume })
}
</script>

然后从 wrapper.vm:

中窥探暴露的 handleResume
// MyComponent.spec.js
import { shallowMount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'

describe('MyComponent', () => {
  it('handles resume', async () => {
    const wrapper = shallowMount(MyComponent)
                                         
    const handleResume = jest.spyOn(wrapper.vm, 'handleResume')

    await wrapper.find('button').trigger('click')
    expect(handleResume).toHaveBeenCalled()
  })
})

demo