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

Vue3使用vue-test-utils与Jest测试setup计算值setData报错

问题根因

你遇到TypeError: Cannot add property myData, object is not extensible报错有两个核心原因:

  • 组件setup()里没有把myData暴露到组件实例上:setup的return只返回了isEditable,Vue组件实例在setup执行完成后会被冻结(不可扩展),后续调用setData往实例上新增不存在的myData属性,就会触发不可扩展的错误。
  • 测试实现思路存在偏差:setup内部声明的局部响应式变量如果没有return,属于组件内部私有状态,外部测试代码无法直接通过setData覆盖,setData仅能修改组件已经对外暴露的、已存在的实例属性。

可行解决方案

方案1:改造组件,把需要测试控制的状态暴露为props(推荐,更符合组件设计规范)

把myObject作为组件入参,测试时直接传参即可,不需要用setData硬改内部状态:
改造后的Hello.vue:

<template>
    <div  v-if="isEditable" id="myEditDiv">
        <button type="button"> Edit </button>
    </div>
</template>
<script lang="ts">
import { computed, defineComponent } from "vue"
export default defineComponent({
    props: {
        myObject: {
            type: Object,
            default: () => ({myName:"", myNumber:""})
        }
    },
    setup(props) {
        const isEditable = computed(() => {
            return !props.myObject.myName.startsWith('DNU')
        })

        return { 
            isEditable   
        }
    }
})
</script>

对应的测试用例Hello.spec.ts:

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

describe('Hello.vue Test', () => {
    it('isEditable returns FALSE if NAME starts with DNU', async () => {
        const testMyObject = {myName:"DNU Bad Name", myNumber:"12345"}
        // 挂载时直接传props,不需要setData
        const wrapper = shallowMount(Hello, {
            props: {
                myObject: testMyObject
            }
        })

        expect(wrapper.vm.isEditable).toBe(false)
        // 校验DOM渲染结果可正常执行
        expect(wrapper.find('#myEditDiv').exists()).toBe(false)
    })  
})

方案2:保留内部状态模式(不推荐)

如果你确实要把myData作为组件内部状态,需要先在setup里把它return出来,让它成为组件实例上已存在的属性,后续setData才能正常修改:
Hello.vue的setup返回值修改为:

return { 
    isEditable,
    myData // 必须先暴露,否则实例上不存在这个属性,setData新增就会报错
}

这种方式测试可信度更低,因为直接修改组件内部私有状态的逻辑,和组件实际运行场景差异较大。

注意:不要尝试在测试中修改setup内部未暴露的私有变量,Vue3的setup闭包内的变量对外是不可访问的,setData没有权限穿透闭包修改内部局部变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:27:48