Vue组件触发事件时Cypress spy未被调用,求排查解决
问题分析与解决
你测试失败的核心原因是把Vue自定义事件的监听器当成props传递了——Vue的自定义事件和props是完全独立的机制,组件通过$emit触发的事件,不能通过props传入监听器来捕获。
修正步骤
1. (可选但推荐)给组件显式声明emits
在Vue3的<script setup>中显式声明要触发的事件,既让组件更规范,也能避免测试中的隐式问题:
<script setup> defineEmits(['onCredits']) </script> <template> <button data-testid="credits" @click="$emit('onCredits')">Click</button> </template>
2. 修正Cypress测试代码
将事件监听器放到listeners选项中(Cypress Vue组件测试支持该选项传递事件监听),而不是props里:
import { createTestingPinia } from '@pinia/testing'; import Button from './Button.vue'; describe('<Button />', () => { it('triggers onCredits event when clicked', () => { const pinia = createTestingPinia({ createSpy: cy.spy(), }); // 创建事件监听spy const onCreditsSpy = cy.spy().as('onCreditsSpy'); cy.mount(Button, { global: { plugins: [pinia], }, // 通过listeners传递事件监听器 listeners: { onCredits: onCreditsSpy, }, }); cy.get('[data-testid=credits]').click(); cy.get('@onCreditsSpy').should('have.been.called'); }); });
另一种写法:通过组件实例监听事件
如果你更习惯直接操作Vue组件实例,也可以在mount后通过组件实例绑定事件监听:
import { createTestingPinia } from '@pinia/testing'; import Button from './Button.vue'; describe('<Button />', () => { it('triggers onCredits event when clicked', () => { const pinia = createTestingPinia({ createSpy: cy.spy(), }); const onCreditsSpy = cy.spy().as('onCreditsSpy'); cy.mount(Button, { global: { plugins: [pinia], }, }).then(({ wrapper }) => { // 给Vue组件实例绑定事件监听 wrapper.vm.$on('onCredits', onCreditsSpy); }); cy.get('[data-testid=credits]').click(); cy.get('@onCreditsSpy').should('have.been.called'); }); });
内容的提问来源于stack exchange,提问作者Joe Czucha
相关产品推荐
相关产品推荐

