Reputation: 3158
I have a snackbar component which I am writing tests for. It contains a child component (A button, when clicked closes the snackbar).
This button emits a @click
event which the parent listens to and runs a method to either close the snackbar or open another.
Is there a way of mocking the $emit
? I can't seem to find something anywhere related to this.
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;
});
});
This is the template of the component:
<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>
Additional Info:
currentSnack
value to null
which hides it.Upvotes: 11
Views: 10321
Reputation: 603
Use trigger to emit an event from a child component. You could do:
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
})
EDIT: For a custom event is more tricky. I am currently mocking the event like this:
const wrapper = shallowMount(Snackbar);
const childWrapper = wrapper.find(ButtomComponent);
childWrapper.vm.$emit('custom', { foo: 'bar' })
Upvotes: 9
Reputation: 3158
Turns out this is quite simple:
import ButtonComponent from '@/components/ButtonComponent.vue';
const { getByRole, getByText } = render(Snackbar, {
components: { ButtonComponent } ,
mocks: { $t: msg => msg }
})
After which point you can use this component like such:
const button = getByRole('button');
Upvotes: 2
Reputation: 483
From what I understand, you want to trigger an emit to test the snackbar. In that case you can use Vue.JS trigger functionality, which triggers an event asynchronously in the wrapper DOM.
You can find more information here : https://vue-test-utils.vuejs.org/api/wrapper/trigger.html
Also, for testing $emit, you can find more information here: https://lmiller1990.github.io/vue-testing-handbook/testing-emitted-events.html#write-a-component-and-test
Upvotes: 0