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

如何用Jest测试Vue计算属性中调用的Props函数是否被调用

如何测试Vue计算属性中调用的Props函数是否被执行

首先,你遇到的问题核心在于没有正确使用Jest的mock函数来追踪函数调用,而且测试写法也不符合Vue组件测试的正确姿势。咱们一步步来解决:

关键思路

要验证props中的函数是否被计算属性调用,你需要:

  • 用Jest创建一个mock函数(这个函数自带调用追踪能力),替代组件props里的myFunction
  • 挂载组件时把这个mock函数传进去
  • 触发计算属性的执行,然后断言mock函数是否被调用

完整测试示例

假设你的组件代码是这样的(修正了原示例里的小问题,比如myFunction调用时要加this.):

<template>
  <!-- 组件模板 -->
</template>

<script>
export default {
  props: {
    myFunction: {
      type: Function,
      default: () => null
    },
    data: {
      type: Boolean,
      default: true
    }
  },
  computed: {
    myComputed() {
      return this.data ? this.myFunction(this.data) : null
    }
  }
}
</script>

对应的Jest测试代码应该这么写:

import { shallowMount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'

describe('MyComponent', () => {
  it('calls myFunction when data is true', () => {
    // 1. 创建Jest mock函数
    const mockMyFunction = jest.fn()

    // 2. 挂载组件,传入mock函数作为props
    const wrapper = shallowMount(MyComponent, {
      props: {
        myFunction: mockMyFunction,
        data: true // 设置data为true,触发计算属性调用函数
      }
    })

    // 3. 访问计算属性,触发它的执行
    wrapper.vm.myComputed

    // 4. 断言mock函数被调用,并且传入了正确的参数
    expect(mockMyFunction).toHaveBeenCalled()
    expect(mockMyFunction).toHaveBeenCalledWith(true)
  })

  it('does NOT call myFunction when data is false', () => {
    const mockMyFunction = jest.fn()

    const wrapper = shallowMount(MyComponent, {
      props: {
        myFunction: mockMyFunction,
        data: false
      }
    })

    wrapper.vm.myComputed

    expect(mockMyFunction).not.toHaveBeenCalled()
  })
})

你之前写法的问题分析

  1. expect(component.props().myFunction()).toHaveBeenCalled():
    • 这里你直接调用了myFunction(),这会执行函数本身,而不是检查它是否被计算属性调用。而且如果myFunction不是mock函数,它根本没有toHaveBeenCalled方法,这就是你看到expect(...).hasBeenCalled is not a function错误的原因。
  2. component.computed.myComputed.call({myFunction : () => 0}):
    • 这种方式手动调用计算属性,但没有绑定正确的组件上下文,而且传入的是普通函数,依然无法追踪调用情况。

额外提示

如果你的计算属性依赖的是组件内部的响应式data,当你修改数据后,需要等待Vue更新DOM和计算属性,这时候要用到await wrapper.vm.$nextTick():

it('calls myFunction when reactive data changes', async () => {
  const mockMyFunction = jest.fn()
  const wrapper = shallowMount(MyComponent, {
    props: { myFunction: mockMyFunction },
    data() {
      return { internalData: false }
    }
  })

  // 修改响应式数据
  wrapper.vm.internalData = true
  await wrapper.vm.$nextTick() // 等待Vue更新

  expect(mockMyFunction).toHaveBeenCalled()
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:07:49