在VueJS中模拟子组件的$emit事件

Riz*_*han 8 javascript vue.js

我有一个正在为其编写测试的小吃栏组件。它包含一个子组件(一个按钮,单击时关闭小吃栏)。

此按钮发出一个@click事件,父级侦听并运行一个方法来关闭小吃栏或打开另一个小吃栏。

有没有办法嘲笑$emit?我似乎无法在任何地方找到与此相关的内容。

import { render, fireEvent, waitFor } from '@testing-library/vue';
import Snackbar from '../Snackbar.vue';
import EventBus from '@/services/EventBus';

describe('Snackbar', () => {
    const role = 'alert';
    
    it('should close snackbar on button click', async () => {
        const type = 'success';

        const { getByRole } = render(Snackbar, {
            // with this the button is inaccessible
            stubs: ['OBButton'],
        });

        await EventBus.$emit('addSnack', {
            type,
        });

        const snackbar = getByRole('alert');

        // this is wrong...
        await fireEvent.click(button);
  
        // this expect should be appropriate.
        expect(snackbar).not.toBeInTheDocument;
    });
});

Run Code Online (Sandbox Code Playgroud)

这是该组件的模板:

<template>
    <div class="snackbar-wrapper elevated">
        <transition name="snack-slide" v-on:after-leave="checkForMoreSnacks">
            <div
                role="alert"
                class="snack-data"
                v-if="currentSnack != null"
            >
                <span class="snack-text">{{ currentSnack.text }}</span>
                <OBButton
                    :text="currentSnack.buttonText"
                    @click="closeCurrentSnack"
                    :type="buttonType"
                ></OBButton>
            </div>
        </transition>
    </div>
</template>
Run Code Online (Sandbox Code Playgroud)

附加信息:

  1. 该组件永远不会被卸载。关闭它意味着设置隐藏它的currentSnack值。null

kam*_*ska 7

使用触发器从子组件发出事件。你可以这样做:

import ButtonComponent from '@/components/ButtonComponent.vue';
import Snackbar from '@/components/Snackbar.vue';

it('should foo', () => {
  const wrapper = shallowMount(Snackbar);
  wrapper.find(ButtonComponent).trigger('click');
  // Your assertions here

})

Run Code Online (Sandbox Code Playgroud)

编辑:对于自定义事件来说更加棘手。我目前正在这样嘲笑这个事件:

const wrapper = shallowMount(Snackbar);
const childWrapper = wrapper.find(ButtomComponent);
childWrapper.vm.$emit('custom', { foo: 'bar' })

Run Code Online (Sandbox Code Playgroud)


Riz*_*han 1

事实证明这很简单:

import ButtonComponent from '@/components/ButtonComponent.vue';

const { getByRole, getByText } = render(Snackbar, {
  components: { ButtonComponent } ,
  mocks: { $t: msg => msg }
})
Run Code Online (Sandbox Code Playgroud)

之后您可以像这样使用该组件:

const button = getByRole('button');
Run Code Online (Sandbox Code Playgroud)