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?
so as class component
One work around is:
const wrapper = mount(ParentComponent, {
stubs: {
functionalComponent: '<div class="functional" />'
}
})
expect(wrapper.findAll('.functional')).toHaveLength(1)
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.
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.
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 馃
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.
@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.
@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.
This is fixed in beta.9
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
@eddyerburgh this is still not working (since beta.9) for the Jest example, see #399
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?
@dvic thanks for the info, I think the issue will be shallow
This should be reopened
@eddyerburgh reopen this please
This issue is still here in v31
@Ruudieboy are you using the find(Component) syntax? You should be able to find a functional component using either name, ref or a selector.
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.
Most helpful comment
This issue is still here in v31