Vue-test-utils: Testing child component event emit

Created on 27 Nov 2017  路  7Comments  路  Source: vuejs/vue-test-utils

Hey guys, love the test utils and thanks so much for the hard work! I just have a quick question about something I'm stuck on. I have a child component that emits an event when a button is clicked. I'm trying to test for the event emit in a parent component but I can't seem to figure it out. I have been using the following from the docs:

wrapper.vm.$emit('foo', 123)

But unfortunately I can't seem to pick up the event fire. Trying to figure out exactly what I'm missing!

Any help would be greatly appreciated!! Thanks

question

Most helpful comment

(sidenote: use triple backticks to format code)

I'm not sure I understand what you are testing - what's the "parent", what's the "child" ?

Is the wrapped component the parent and you try to emulate an emit from the child? Then that won't work. What you are doing is emitting an event within the parent component, not from the child. That's why it's not reacting. The documentation you read was about testing the event API of a component, not mocking an event of a child component within a parent component.

So what you would have to do is something like this:

wrapper.vm.$refs.childComponent.$emit('foo', 123)

...assuming you have specified a ref on the child in the parent's template.

Alternatively you could select the element that emits the click and actually trigger the click event on it

wrapper.find('.my-button').trigger('click')

All 7 comments

How are you trying to pick up the event?

with this lib, you would do this:

expect(wrapper.emitted().foo[0])toBe(123)

https://vue-test-utils.vuejs.org/en/api/wrapper/emitted.html

Hey @LinusBorg, thanks for your reply. That's exactly what I was trying but no luck. Basically, all the parent component does is listen for the event and the splice an object out of an array. The other part of the test case was to check how many items are in the list. After the event there should only be 1 but the list is actually containing 2.

The event is firing but the function doesn't seem to be firing. Child component as it's being used in the parent component:

<time-constraint v-for="(time, index) in times" v-bind:time="time" v-bind:index="index" v-bind:key="index" v-on:removeTimeConstraint="removeTime(index)" ></time-constraint>

The removeTime(index) function never get's called for some reason.

(sidenote: use triple backticks to format code)

I'm not sure I understand what you are testing - what's the "parent", what's the "child" ?

Is the wrapped component the parent and you try to emulate an emit from the child? Then that won't work. What you are doing is emitting an event within the parent component, not from the child. That's why it's not reacting. The documentation you read was about testing the event API of a component, not mocking an event of a child component within a parent component.

So what you would have to do is something like this:

wrapper.vm.$refs.childComponent.$emit('foo', 123)

...assuming you have specified a ref on the child in the parent's template.

Alternatively you could select the element that emits the click and actually trigger the click event on it

wrapper.find('.my-button').trigger('click')

Hey @LinusBorg, sorry about that. Back ticks are not my friend today! I have a TimeConstraints (parent) component that will contain a list of TimeConstraint (child) components. You are correct I want to mock event of a child component within a parent component. The above code looks exactly what I need, I will give it a try now. Thanks for your reply

Hey @LinusBorg that worked for me. Thanks for your help!

I'm going to leave this here, as the situation for a form submit button is different. I'm assuming that, because the tests don't take place with a browser DOM, clicking a button to submit a form won't trigger the form 'submit' event, so your code will have to listen for that event instead, like this example:

it("renders dashboard component after successful login", () => {
        // if your child component needs to submit data, set that first
        wrapper.find(Login).vm.$data.credentials.username = "Ozzy";
    wrapper.find(Login).vm.$data.credentials.password = "notarealpassword";

        // this is the event you need to trigger
    wrapper.find("form").trigger('submit');

    expect(wrapper.find(Login).element).to.be.undefined;
        // dashboard is whatever you see after logging in
    expect(wrapper.find(DashBoard).element).to.not.be.undefined; 
});

Hope this helps anyone

Was this page helpful?
0 / 5 - 0 ratings