Vue-test-utils: Triggering custom events

Created on 3 Nov 2017  路  13Comments  路  Source: vuejs/vue-test-utils

I was trying to test a custom event (in the parent) that is emitted by a child component. However, using wrapper.trigger we can only use DOM events.

Would it be possible to add custom events?

If not, is there a way to test custom events from within the shallow rendered parent component?

My testcase is that the child emits an event and the parent should execute a function on occurrence of this event.

feature request

Most helpful comment

You can call $emit on the wrapper vm

wrapper.vm.$emit('foo')

We're hesitant to add this as a feature because there are many possible aliases like this, and we want to keep the API small.

If lots of people would find this feature useful, we can consider adding it.

It's also worth us adding a note on this to the trigger docs. Is anyone able to make a PR adding details on this?

All 13 comments

You can call $emit on the wrapper vm

wrapper.vm.$emit('foo')

We're hesitant to add this as a feature because there are many possible aliases like this, and we want to keep the API small.

If lots of people would find this feature useful, we can consider adding it.

It's also worth us adding a note on this to the trigger docs. Is anyone able to make a PR adding details on this?

@eddyerburgh I can do the PR next week if noone gets there first.

There was a point where I wanted this feature, but after playing around a bit, I don't think it is necessary. I'll think a bit more about it and if I come up with some good use cases, post them.

@eddyerburgh I think it is clear from the docs, I just wasn't sure why only DOM events could be triggered.

Anyway, I made my test now using

const stub = jest.fn();
wrapper.vm.$on('hit', stub);
wrapper.vm.$emit('hit');
expect(stub).toBeCalled();

And the test passes. However, this feels a bit clumsy. I am not even sure what exactly I am testing here?

It looks like you're testing Vue functionality, rather than logic in your code.

I got started on a small demo, and thought about how I I would expect the docs (wrapper/emitted) to look, but couldn't really come up with a big improvement on them.

Unless @eddyerburgh has something you'd like added, I think we can just close this for now. The main problem seems to not be the docs, but a lack of how/what to test - maybe we should add more targetted/details guides.

@eddyerburgh I agree I was testing Vue functionality itself. With the help of issue #145, I am now on my way testing my own Vue code. Thanks for the clarification!

You can call $emit on the wrapper vm

wrapper.vm.$emit('foo')

We're hesitant to add this as a feature because there are many possible aliases like this, and we want to keep the API small.

If lots of people would find this feature useful, we can consider adding it.

It's also worth us adding a note on this to the trigger docs. Is anyone able to make a PR adding details on this?

how to testing custom event params with $event, I read doc, the doc don't mention.

changeValue(type, event) {
        const value = event.target.value;
        const eventName = type ? 'behindValue' : 'frontValue';
        this.$emit('on-change');
        this.$emit(`update:${eventName}`, value);
},
// in unit  test file
/*
const mock = jest.fn();
const beforeInput = wrapper.find('input.group_input_before');
beforeInput.vm.$emit('on-change', 0,  {target: {value: 100}});
wrapper.vm.$on('update:frontValue', mock);
 expect(mock).toBeCalledWith(100);
*/

error:

[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'value' of undefined"

It looks like event.target is undefined here. Try vm.$emit('change').

You could try to mock the method you are expecting to be called, and assert against that. Eg:

const mock = jest.fn()
const wrapper = shallowMount(Component, {
  methods: {
    frontValue: mock
  }
}

wrapper.find('.....').vm.$emit('.....')
expect(mock).toHaveBeenCalledWith(100)

If you can post the rest of your source code, I can help you get the test working.

It looks like event.target is undefined here. Try vm.$emit('change').

You could try to mock the method you are expecting to be called, and assert against that. Eg:

const mock = jest.fn()
const wrapper = shallowMount(Component, {
  methods: {
    frontValue: mock
  }
}

wrapper.find('.....').vm.$emit('.....')
expect(mock).toHaveBeenCalledWith(100)

If you can post the rest of your source code, I can help you get the test working.

I having a test the same as your advice, then I see the coverage, it said the changeValue method didn't cover, so I want to test it.
I put my source code in codesandbox, it only source code

I invoke the $emit('on-change') and log the beforeInput.emitted(), then I see it's an empty array, so the $emit function that utils provide can't pass the vue $event params in custom event ?
image

BTW, I must have a try..catch wrapper the value = event.target.value, then it can pass the the component function, but do you think it's ugly

First, Thx for you reply 馃槂 .
Then it's my fault, I misunderstand about the vm.$emit function when I manual invoke it's only need a params that is the $event params pass into the listener.
and I change the unit test to this, it light the green pass.

test('testing changeValue fn can invoke the custom event', () => {
    const mock = jest.fn();
    const Event = {target: {value: 16}};
    const InputComponent = shallowMount(inputGroup, {
      propsData: {
        frontValue: 12,
        behindValue: 14,
      },
      listeners: {
        'update:behindValue': mock,
        'update:frontValue': mock,
      },
    });
    const frontInput = InputComponent.find('input.group_input_before');
    const afterInput = InputComponent.find('input.group_input_after');
    frontInput.vm.$emit('on-change', Event);
    afterInput.vm.$emit('on-change', Event);
    // console.log(InputComponent.emitted());
    expect(mock).toHaveBeenCalledTimes(2);
  });

the source code was in here , if you having less time, forget it.

Looks like you solved your problem, then?

Looks like you solved your problem, then?

yes

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AustinGil picture AustinGil  路  3Comments

vwxyutarooo picture vwxyutarooo  路  3Comments

vilarinholeo picture vilarinholeo  路  3Comments

matt-sanders picture matt-sanders  路  3Comments

dlumbrer picture dlumbrer  路  3Comments