如何使用 Vue Test Utils 测试全局事件总线? [英] How to Test a Global Event Bus With Vue Test Utils?

查看:33
本文介绍了如何使用 Vue Test Utils 测试全局事件总线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习如何测试通过全局事件总线发出的事件.这是我不知道该怎么做的地方有一些注释的代码.

//EvtBus.js从'vue'导入Vue;导出 const EvtBus = new Vue();

<模板><div><输入类=优惠券代码"类型=文本"v-model="代码"@input="验证"><p v-if="valid">兑换券:{{ message }}</p>

<脚本>从 '../EvtBus.js' 导入 { EvtBus };导出默认{数据 () {返回 {代码: '',有效:假,优惠券:[{代码:'50OFF',折扣:50,消息:50% 折扣!"},{代码:'免费',折扣:100,消息:完全免费!"}]};},创建(){EvtBus.$on('coupon-applied', () => {//console.info('在组件上有一个优惠券应用事件');});},方法: {证实 () {//将优惠券代码提取到一个数组中并检查该数组是否//包括输入的优惠券代码.this.valid = this.coupons.map(coupon =>coupon.code).includes(this.code);如果(this.valid){this.$emit('应用');//我从来没有在coupon-code.spec.js上看到这个EvtBus.$emit('优惠券申请');}}},计算:{信息 () {返回 this.coupons.find(coupon =>coupon.code === this.code).message;}}}

//tests/coupon-code.spec.js从期望"导入期望;从 '@vue/test-utils' 导入 { mount };从'../src/components/CouponCode.vue'导入优惠券代码;从 '../src/EvtBus.js' 导入 { EvtBus };描述('提醒',()=> {让 wrp;beforeEach(() => {wrp = 挂载(优惠券代码);});it('在应用有效优惠券代码时广播百分比折扣', () => {let code = wrp.find('input.coupon-code');code.element.value = '50OFF';code.trigger('输入');console.log(wrp.emitted('applied'));////我从来没有在输出上看到这个.//我如何通过全局事件总线而不是测试它//从组件实例发出的事件?//EvtBus.$on('coupon-applied', () => {console.log('优惠券是通过事件总线申请的');});//通过,但不使用 EvtBus 实例.expect(wrp.emitted('applied')).toBeTruthy;});});

所以,我的疑问是如何测试全局事件总线是否在使用该事件总线的组件内部发出和侦听事件.

那么,是否可以使用 Vue Test Utils 测试全局事件总线,或者我应该使用其他方法?

解决方案

如果组件使用全局 EventBus,例如从给定组件外部导入并分配给 window.EventBus,则可以使用全局 Vue 实例将 $on 或 $emit 事件重定向到包装器的 vm 实例.这样你就可以继续编写测试,就像组件通过 this.$emit 而不是 EventBus.$emit 发出一样:

it('点击设置"按钮会发出openSettings"', () => {global.EventBus = new Vue();global.EventBus.$on('openSettings', (data) => {wrapper.vm.$emit('openSettings', data);});//组件发出 `EventBus.$emit('openSettings')`期望(wrapper.emitted('openSettings')).toBeTruthy();//经过});

I am trying to learn how to test events emitted through a global Event Bus. Here's the code with some comments in the places I don't know what to do.

// EvtBus.js
import Vue from 'vue';
export const EvtBus = new Vue();

<!-- CouponCode.vue -->
<template>
    <div>
        <input
            class="coupon-code"
            type="text"
            v-model="code"
            @input="validate">
        <p v-if="valid">
            Coupon Redeemed: {{ message }}
        </p>
    </div>
</template>

<script>

import { EvtBus } from '../EvtBus.js';

export default {
    data () {
        return {
            code: '',
            valid: false,

            coupons: [
                {
                    code: '50OFF',
                    discount: 50,
                    message: '50% Off!'
                },
                {
                    code: 'FREE',
                    discount: 100,
                    message: 'Entirely Free!'
                }
            ]
        };
    },

    created () {
        EvtBus.$on('coupon-applied', () => {
            //console.info('had a coupon applied event on component');
        });
    },

    methods: {
        validate () {
            // Extract the coupon codes into an array and check if that array
            // includes the typed in coupon code.
            this.valid = this.coupons.map(coupon => coupon.code).includes(this.code);
            if (this.valid) {
                this.$emit('applied');
                // I NEVER see this on the coupon-code.spec.js
                EvtBus.$emit('coupon-applied');
            }
        }
    },

    computed: {
        message () {
            return this.coupons.find(coupon => coupon.code === this.code).message;
        }
    }
}
</script>

// tests/coupon-code.spec.js
import expect from 'expect';
import { mount } from '@vue/test-utils';
import CouponCode from '../src/components/CouponCode.vue';
import { EvtBus } from '../src/EvtBus.js';

describe('Reminders', () => {
    let wrp;

    beforeEach(() => {
        wrp = mount(CouponCode);
    });

    it('broadcasts the percentage discount when a valid coupon code is applied', () => {
        let code = wrp.find('input.coupon-code');
        code.element.value = '50OFF';
        code.trigger('input');

        console.log(wrp.emitted('applied'));

        //
        // I NEVER see this on the outpout.
        // How can I test it through a global event bus rather than
        // an event emitted from the component instance?
        //
        EvtBus.$on('coupon-applied', () => {
            console.log('coupon was applied through event bus');
        });

        // Passes, but not using EvtBus instance.
        expect(wrp.emitted('applied')).toBeTruthy;

    });
});

So, my doubt is how to test that the global event bus is emitting and listening to events inside components that use that event bus.

So, is it possible to test the global Event Bus using Vue Test Utils or I should use another approach?

解决方案

If component is using global EventBus, eg that's imported outside of given component and assigned to window.EventBus, then it's possible to use global Vue instance to redirect $on or $emit events to wrapper's vm instance. That way you can proceed writing tests as if component is emitting via this.$emit instead of EventBus.$emit:

it('clicking "Settings" button emits "openSettings"', () => {
    global.EventBus = new Vue();
    global.EventBus.$on('openSettings', (data) => {
        wrapper.vm.$emit('openSettings', data);
    });

    // component emits `EventBus.$emit('openSettings')`

    expect(wrapper.emitted('openSettings')).toBeTruthy(); // pass
});

这篇关于如何使用 Vue Test Utils 测试全局事件总线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆