Reputation: 1983
I have a set of parent & child vue components. The child emits an event that the parent handles. I'd like to test that it handles the custom event correctly, but I am stuck.
Parent.vue
<template>
<div id="app" class="container">
<!-- phonebook -->
<ChildComponent
class="row mt-4"
@customEvent="val => customEventHandler(val)"
></ChildComponent>
</div>
</template>
<script>
import ChildComponent from './components/ChildComponent.vue'
export default {
name: 'App',
components: {
ChildComponent,
},
data() {
return {
test: [1, 2, 3, 4]
};
},
methods: {
customEventHandler(id) {
// removes item `id` from the `test` array
this.test = this.test.filter((item) => item !== id);
},
}
};
</script>
This is one thing I've tried:
Parent.spec.js
import { mount, shallowMount } from "@vue/test-utils";
import Parent from '../../src/Parent.vue';
import ChildComponent from '../../src/components/ChildComponent.vue';
describe('customEvent event', () => {
beforeEach(() => {
parent = mount(Parent, {
data() {
return {
test: [1, 2, 3, 4]
};
},
});
});
it('should trigger the customEventHandler method', async() => {
const spy = jest.spyOn(parent.vm, 'customEventHandler');
await parent.findComponent(ChildComponent).trigger('customEvent', 2);
expect(spy).toHaveBeenCalled();
})
})
The test above fails and I'm not sure why.
I've also tried the following tests:
// check what the spy has been called with
expect(spy).toHaveBeenCalledWith(2);
// test the side-effects of the `customEventHandler` method
expect(parent.vm.test.length).toEqual(3)
These also fail - it's as though the event isn't being triggered at all (is that it?), or I'm trying to test something that isn't possible.
Is there an accepted way to test a parent component's handling of an event emitted by a child component?
Upvotes: 4
Views: 5266
Reputation: 138196
trigger()
only works for native DOM events. For custom events, use wrapper.vm.$emit()
(and no need to await
it):
// await parent.findComponent(ChildComponent).trigger('customEvent', 2);
// ^^^^^^^ ❌
parent.findComponent(ChildComponent).vm.$emit('customEvent', 2);
Vue 2 does not support spying on methods from the wrapper.vm
instance, so the spying needs to be done on the component definition (Parent.methods
) before mounting:
// const spy = jest.spyOn(parent.vm, 'customEventHandler');
// ^^^^^^^^^ ❌ not supported in Vue 2
const spy = jest.spyOn(Parent.methods, 'customEventHandler')
const parent = mount(Parent)
Note that Vue 3 does support spying via wrapper.vm
.
Upvotes: 8