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
相关产品推荐
相关产品推荐

