Vue-test-utils: Testing events when using $listeners

Created on 3 Oct 2019  路  6Comments  路  Source: vuejs/vue-test-utils

Version

1.0.0-beta.29

Reproduction link

https://github.com/lee-chase/vue-test-utils-listeners

Steps to reproduce

Given a simple button wrapper component

<template>
  <button v-bind="$attrs" v-on="$listeners">
    <div class="content">{{ buttonText }}</div>
  </button>
</template>

I have been unable to test the click event as follows:

  it("Raises click event when clicked", () => {
    const wrapper = shallowMount(MyButton2);
    wrapper.find("button").trigger("click");
    expect(wrapper.emitted().click).toBeTruthy();
  });

If I change the component to explicitly handle clicky it works, but this is not desirable for native component wrappers and negates the usefulness of $listeners

<template>
  <button v-bind="$attrs" v-on="$listeners" @click="$emit('click')>
    <div class="content">{{ buttonText }}</div>
  </button>
</template> 

What is expected?

It should be possible to test events surfaced through $listeners

What is actually happening?

No event is raised

Most helpful comment

It would be nice to show how the OP was supposed to write his test rather than just closing the issue. I was trying to do the same thing as the OP and finally figured out how to write the test. Here is how the test needs to be written:

  it("Raises click event when clicked", () => {
    // Arrange
    const onClick = jest.fn();
    const wrapper = shallowMount(MyButton2, listeners: { click: onClick });
    // Act
    wrapper.find("button").trigger("click");
    // Assert
    expect(onClick).toHaveBeenCalled();
  });

we need to create a listener on the mount to simulate somebody doing an @click on the component under test. We use a jest.fn() to make it easy to test that the click handler was called.

All 6 comments

Unless I am mistaken I'm don't believe emitted works the way you are expecting.

It doesn't detect events emitted by HTML elements. It only works on the component wrapper and detects events that the component itself emits.

@eddyerburgh can be closed!

馃憤

It would be nice to show how the OP was supposed to write his test rather than just closing the issue. I was trying to do the same thing as the OP and finally figured out how to write the test. Here is how the test needs to be written:

  it("Raises click event when clicked", () => {
    // Arrange
    const onClick = jest.fn();
    const wrapper = shallowMount(MyButton2, listeners: { click: onClick });
    // Act
    wrapper.find("button").trigger("click");
    // Assert
    expect(onClick).toHaveBeenCalled();
  });

we need to create a listener on the mount to simulate somebody doing an @click on the component under test. We use a jest.fn() to make it easy to test that the click handler was called.

It would be nice to show how the OP was supposed to write his test rather than just closing the issue. I was trying to do the same thing as the OP and finally figured out how to write the test. Here is how the test needs to be written:

  it("Raises click event when clicked", () => {
    // Arrange
    const onClick = jest.fn();
    const wrapper = shallowMount(MyButton2, listeners: { click: onClick });
    // Act
    wrapper.find("button").trigger("click");
    // Assert
    expect(onClick).toHaveBeenCalled();
  });

we need to create a listener on the mount to simulate somebody doing an @click on the component under test. We use a jest.fn() to make it easy to test that the click handler was called.

And how you test implementation of the function with such test?

@Konstantin1996
In the case that I was testing, I was passing the event handlers through to a component within my component. So I was interested in ensuring that I was passing the event handlers correctly. It was the mechanism of @click that I was trying to test, not the implementation of the function that @click calls.

If you are looking at this for testing a component that needs to do something with the @click, then I think it is more straight forward and following the usual documentation.

You can either pull the click handler out into its own function that can be called directly to ensure that it does what it is supposed to do, or you can trigger the click like above and then test for the side effects of that function having been called.

Was this page helpful?
0 / 5 - 0 ratings