Skip to content

Testing emit from $root #169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jskogelin opened this issue Nov 10, 2020 · 8 comments
Closed

Testing emit from $root #169

jskogelin opened this issue Nov 10, 2020 · 8 comments

Comments

@jskogelin
Copy link

Any recommendations on testing functionality that depends on listening to events emitted via $root.$emit? Like you would via wrapper.vm.$root.$emit for example using vue-test-utils. Haven't been able to find anything in the docs.

Thanks for a great library!

@afontcu
Copy link
Member

afontcu commented Nov 10, 2020

Hi! Can you share a component/test example?

@jskogelin
Copy link
Author

Sure! The created hook of the component I would like to test looks something like this:

export default {
  name: 'ComponentToTest',
  created () {
    this.$root.$on('event', () => {
      // This runs an axios request and conditionally displays a component based on the response
      this.fetchFromServerAndDisplayElement()
    })
  }
  ...
}

Template of ComponentToTest

<template>
  <component-to-display v-if="requestReturnedTrue">
    displayThis
  </component-to-display>
</template>

Then, in my test

it('should display a component on root emit', function () {
  const { getByText } = render(ComponentToTest, ...)
  
  // Here I somehow want to test that the component responds to the event
  // emitted via $root.$emit

  expect(getByText('displayThis')).toBeInTheDocument()
})

@afontcu
Copy link
Member

afontcu commented Nov 11, 2020

Hi! Vue Testing Library offers a third parameter which gives you access to the vue instance (https://github.com/testing-library/vue-testing-library/blob/master/src/vue-testing-library.js#L51-L53):

render(Component, {}, vue => {})

maybe you can leverage it to trigger the event? let me know how it goes!

@jskogelin
Copy link
Author

Been digging through the instance and haven't been able to find anything that helps me trigger the event unfortunately.

I've also attempted to mock $root by setting it to a Vue instance i have access to, but no luck.

@jskogelin
Copy link
Author

Let me know if this is a feature the library needs and I'll send in a PR!

@jueinin
Copy link

jueinin commented Nov 12, 2020

need to get the vue instance object too! in some special environmens, I need to mock some methods on vm

@lmiller1990
Copy link
Collaborator

lmiller1990 commented Nov 14, 2020

Can you just wrap the component?

const Wrapper = (comp) => {
  return {
    render: (h) => h('div', h(comp))
  }
}

Now you can do mount(Wrapper) and since Wrapper is the $root, you should be able to do see the emitted events on it. Note: I have not tried this, I just made it up on the spot. It might not work at all.

I also noticed $on no longer exists in Vue 3, you might want to keep this in mind.

@jskogelin
Copy link
Author

Can you just wrap the component?

Thank you! Can't believe I didn't think of this sooner. This was my solution:

it('should respond to root emit', function () {
    const Wrapper = {
      mounted () {
        this.$root.$emit('emit-to-test')
      },

      render (h) {
        return h('div', [ h(ComponentToTest) ])
      }
    }

    // ...assert stuff
})

I also noticed $on no longer exists in Vue 3, you might want to keep this in mind.

Thanks for the heads up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants