Vue-test-utils: Testing this.$root.$emit with wrapper.emitted

Created on 24 Sep 2018  路  5Comments  路  Source: vuejs/vue-test-utils

Version

1.0.0-beta.25

Reproduction link

https://jsfiddle.net/rossta/50wL7mdz/749387/

Steps to reproduce

Given a component that triggers an event on its root via this.$root.$emit:

// ChildComponent
export default {
  mounted() {
    this.$root.$emit('say', 'New message!')
  },
  render: h => h('div', 'Child content')
};

Test the event is emitted using the wrapper API, i.e., wrapper.emitted('say'):

import { mount } from '@vue/test-utils'
import ChildComponent from './ChildComponent.vue'

describe('ChildComponent', () => {
  it('emits event to $root', () => {
    const wrapper = mount(ChildComponent)
    expect(wrapper.emitted('say')).toBeTruthy() // test fails in 1.0.0-beta.25
  })
})

What is expected?

In version 1.0.0-beta.16, the wrapper.emitted('say') test passes for the event emitted on the component's root.

What is actually happening?

In version 1.0.0-beta.25, the test does not pass.

I'm actually not sure what the intended behavior since I do not believe it is documented; I wanted to raise the issue just in case this change was not intended.


We came across this change in behavior while upgrading from 1.0.0-beta.16 to 1.0.0-beta.25.

For those interested, an alternative way to test this behavior is suggested in #481 by overriding the parentComponent option, which will behave as the $root component.

feature request

Most helpful comment

You can do this by creating a wrapper from the $root:

it('captures emitted events on $root instance', () => {
  const wrapper = mount(TestComponent)
  wrapper.vm.$root.$emit('foo')
  const rootWrapper = createWrapper(wrapper.vm.$root)
  expect(rootWrapper.emitted('foo')).to.exist
})

All 5 comments

I've marked this as a feature request since (as you suspected) this is not currently intended behavior, but I can see that it could be useful.

You can do this by creating a wrapper from the $root:

it('captures emitted events on $root instance', () => {
  const wrapper = mount(TestComponent)
  wrapper.vm.$root.$emit('foo')
  const rootWrapper = createWrapper(wrapper.vm.$root)
  expect(rootWrapper.emitted('foo')).to.exist
})

I did what you did but

import { shallowMount, createLocalVue, mount, createWrapper } from '@vue/test-utils';
import Vue from 'vue'
import Modal from './Modal.vue';
import {i18n} from '../../plugins/i18n-setup'

const localVue = createLocalVue()

Vue.component('Modal', Modal)

const Parent = Vue.component("Parent", {
    name: "Parent",
    template: "<div><Modal /></div>"
})

describe('Modals', () => {
    it('should create an empty modal', () => {

        const wrapper = mount(Parent, {
            localVue,
            i18n
        })
        // console.log(wrapper.html())

        wrapper.vm.$root.$emit('openModal', {
            activeComponent: 'AddSection',
            title: "I am a modal title"
        })

        const rootWrapper = createWrapper(wrapper.vm.$root)
        console.log(wrapper.emitted('openModal'));
        // expect(rootWrapper._emitted('openModal')).to.exist
        Vue.nextTick(() => {
            console.log(wrapper.html())
        })
    })
})

It should normally populate the Modal with slot but it doesn't

Catching the event doest mean it does function in it ?

I have a parent

<div>
 <Modal/>
<Child />
</div>

the Mocal listen to $root.$on("openModal")

ok my bad it is working...

Was this page helpful?
0 / 5 - 0 ratings