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

Vue3组件Cypress单元测试报错:无法读取isBalanced方法

问题原因及修复方案

问题原因

你在测试中尝试访问Description.methods.isBalanced,但Vue3的<script setup>语法是闭合作用域,里面定义的函数、变量默认不会暴露到组件实例上,所以Description.methods根本不存在,直接导致报错"Cannot read properties of undefined (reading 'isBalanced')"。

另外还有两个次要问题:

  • 测试里的cy.callsIsBalancedOnce()不是Cypress内置命令,无法直接使用
  • 组件里的sepcialChars存在拼写错误(应为specialChars),虽不触发当前报错,但会影响后续逻辑

修复方案

1. 显式暴露组件内部方法

在Vue3的<script setup>中,需要用defineExpose主动暴露要测试的方法,修改组件代码:

<template>
    <input id="description" v-model="description" />
{{ message }}
</template>
<script setup>
import { ref,computed, defineExpose } from 'vue'

// states
const description = ref('')
const specialChars = ['(', ')', '[', ']', '{', '}']
const balancedMessage = 'The text is balanced.'
const UnbalancedMessage = 'The text is not balanced.'

//computed
const message = computed(() => isBalanced() ? balancedMessage : UnbalancedMessage)

// methods
function isBalanced() {
    const strArr = description.value.split('')
    let isBalnce = true
    let caps = []
    for (let s of strArr) {
        if (isSpecial(s)) {
            const isOpen = isOpening(s)
            if (isOpen) {
                caps.push(s)
            } else {
                const lastCap = caps[caps.length - 1]
                if (lastCap === findPair(s))
                    caps.pop()
                else
                    isBalnce = false
            }
        }
    }
    if (caps.length) isBalnce = false
    return isBalnce
}
function isSpecial(character) {
    return specialChars.includes(character)
}
function isOpening(specialChar) {
    const index = specialChars.indexOf(specialChar)
    return index % 2 === 0
}
function findPair(specialChar) {
    const index = specialChars.indexOf(specialChar)
    const pairIndex = index - 1
    return specialChars[pairIndex]
}

// 暴露方法到组件实例
defineExpose({
  isBalanced
})
</script>

2. 修改测试代码,从组件实例获取方法

Cypress挂载组件后,可通过Cypress.vue访问组件实例,再对实例上的方法进行spy:

import Description from '../Description.vue'
const balancedMessage = 'The text is balanced.'
const UnbalancedMessage = 'The text is not balanced.'

describe('Description Component | src/components/Description.vue', () => {
  beforeEach(() => {
    cy.mount(Description)
    // 从组件实例获取isBalanced并创建spy
    cy.wrap(Cypress.vue).then(vm => {
      cy.spy(vm, 'isBalanced').as('isBalanced')
    })
  })
  context('Validation', ()=>{
    it('Passing a balanced text with no special character', ()=>{
        cy.get('input#description').type('Hi How are you doing today?')
        cy.contains(balancedMessage)
        // 用Cypress内置断言验证调用次数
        cy.get('@isBalanced').should('have.been.calledOnce')
    })
  })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:51:02