Skip to content
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

Can't find functional component #296

Closed
LucienLee opened this issue Dec 25, 2017 · 18 comments
Closed

Can't find functional component #296

LucienLee opened this issue Dec 25, 2017 · 18 comments
Labels

Comments

@LucienLee
Copy link

Hi there,
I found that find can't get functional component.
For instance:

import { mount } from 'vue-test-utils'
import functionalComponent from './functionalComponent'
import ParentComponent from './ParentComponent'

const wrapper = mount(ParentComponent);
wrapper.find(functionalComponent); // Can't find it

I know that functional component is instanceless, so it's understandable that wrapper can't find it directly. However, that is really hard to test. One way is use ref to mark component but that is not ease-to-use when using multiple functional components in the same time.

Any suggestions to test functional component? Otherwise, how do you think about supporting finding functional component?

@doun
Copy link

doun commented Dec 25, 2017

so as class component

@lmiller1990
Copy link
Member

lmiller1990 commented Dec 25, 2017

One work around is:

const wrapper = mount(ParentComponent, {
  stubs: {
    functionalComponent: '<div class="functional" />'
  }
})

expect(wrapper.findAll('.functional')).toHaveLength(1)

@robcresswell
Copy link
Contributor

For the sake of CSS / theming, most components should have specific class names or IDs anyway, depending on your code design. The best way to do this would be as above, using find() with a relevant selector.

@LucienLee
Copy link
Author

Thanks your opinions. It's not not elegant but acceptable. One last thing, should we add how to test functional component in doc? I can help that.

@eddyerburgh eddyerburgh mentioned this issue Dec 26, 2017
13 tasks
@eddyerburgh
Copy link
Member

We'll add support for finding functional components.

One thing I'm wondering, since functional components don't create an instance, should we create a new Wrapper for them. This would include a vnode for the component, return true for isVueComponent, but have no vm 🤔

@lmiller1990
Copy link
Member

Is there another way do to it? That seems like a lot to do just for functional components (I suppose that's a big just, they are kind of important).

I am still learning about how vue-test-utils works internally. I suppose a new wrapper would be very simple, since it would not need a lot of the stuff existing wrappers need, since functional components cannot emit, or do other fancy things.

@robcresswell
Copy link
Contributor

@eddyerburgh As long as it's well documented on the disparity between the wrappers (vm vs no vm), it should be fine. I could imagine there being some confusion otherwise.

@LucienLee
Copy link
Author

LucienLee commented Dec 27, 2017

@eddyerburgh it's awesome to have find feature on functional components.
Supposedly people would know the functional component is instanceless, so they shouldn't expect that it has vm instance. Besides, the test of the functional component would focus on props mapping to view structure and listeners called on triggering. Hence, I think people will use attribute, hasStyle, html, trigger...API (might only using them) rather than vm instinctively.

Overall, don't worry about that. I think that people probably would not try to use vm on functional components. I agree @robcresswell if it's documented, it doesn't matter creating a new Wrapper.

@eddyerburgh
Copy link
Member

This is fixed in beta.9

@38elements
Copy link
Contributor

The following code does not work.

functional.vue

<script>
export default {
  name: 'functional',
  functional: true,
  render: (createElement) => createElement('div', 'This is a functional component')
}
</script>

parent.vue

<template>
  <div>
    <functional />
  </div>
</template>

<script>
import functional from './functional.vue'
export default {
  name: 'parent',
  components: {
    functional
  }
}
</script>
import { mount } from '~vue-test-utils'
import Functional from '~resources/components/functional.vue'
import Parent from '~resources/components/parent.vue'

describe('mount', () => {
  it('functional', () => {
    const wrapper = mount(Parent)
    const functional = wrapper.find(Functional)
    expect(functional.text()).to.equal('This is a functional component')
  })
})

Error: [vue-test-utils]: find did not return Component, cannot call text() on empty Wrapper

@dvic
Copy link

dvic commented Feb 1, 2018

@eddyerburgh this is still not working (since beta.9) for the Jest example, see #399

@dvic
Copy link

dvic commented Feb 1, 2018

I notice that the example in #399 uses shallow with functional components that have props, might this be causing an issue that previously has not been addressed?

@eddyerburgh
Copy link
Member

@dvic thanks for the info, I think the issue will be shallow

@Djaler
Copy link
Contributor

Djaler commented Jul 17, 2019

This should be reopened

@Djaler
Copy link
Contributor

Djaler commented Oct 1, 2019

@eddyerburgh reopen this please

@Ruudieboy
Copy link

This issue is still here in v31

@lmiller1990
Copy link
Member

@Ruudieboy are you using the find(Component) syntax? You should be able to find a functional component using either name, ref or a selector.

@Ruudieboy
Copy link

Ruudieboy commented Feb 12, 2020

Yes im using wrapper.find({ name: 'aa-header' }) for example. Where aa-header is the name of the functional component.

My current workaround is to just add a class or id to the component and find it that way.

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

No branches or pull requests

9 participants