'Vue Test utils custom event trigger is not working

Parent Component

<div>
 <DropdownContainer v-model="selectedTitle" title="dropdown-title" 
                    :options="dropdownOption" @load-data="doSomething"
                    dropdown-data-test="dropdown-test"/>
</div>

doSomething() {
 console.log('I am getting called');
}

Child Component

<template>
<Dropdown :model-value="modelValue" :options="options" :data-test="dropdownDataTest"
          @change="emitEvent">
</Dropdown>
</template>

export default {
name: "DropdownContainer",
emits: ['update:modelValue', 'load-data'],
methods: {
  emitEvent(event) {
    this.$emit('update:modelValue', event.value);
    this.emitChangeEvent && this.$emit('load-data')
  }
}
}

I am trying to write test for my parent component, where I want to trigger doSomething method and assert on that operation.

Parent component test

 it('should call dropdown load-data method',async () => {
        const wrapper = mount(Parent)
        const dropdown = wrapper.findComponent('[data-test="dropdown-test"]')

        await dropdown.trigger('load-data');
    });

Now, here when I run the test, the test passes as there is no assertion but I don't see the parent's component doSomething console log - I am getting called.

But if I remove the emits block(load-data) from Child component emits: ['update:modelValue', 'load-data'] and change it to emits: ['update:modelValue']

Then, my parent component test passes and prints the console log, it means it actually call the doSomething method.I am not sure why?

Is there anything that I am doing wrong because as per official docs we should list all the emitted events but my test is failing because of that. Thanks in advance.

Note: I am using Vue3, Vue/test-utils and Primevue component library, and I tested the feature is working fine, its just the test issue.



Solution 1:[1]

The problem is with the .trigger. As docs says it fires event on the DOM node. If you explicitly specifying the event in emits block it says that your component will fire it. Otherwise VTU just trigger the load-data event as DOM node event.

In your case you shoud use $emit

wrapper.findComponent('[data-test="dropdown-test"]').vm.$emit('load-data')

await wrapper.vm.$nextTick() // Wait until $emits have been handled
// then
expect(wrapper.emitted('first-event'))...
expect(wrapper.emitted('second-event'))...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1