-
Notifications
You must be signed in to change notification settings - Fork 668
shallowMount: Stub child component props (explicit defined in componente or from mixin) #987
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
Comments
Maybe this is a better api: const wrapper = shallowMount(ParentComponent, {
stubs: {
'ChildComponent': {
// mixins: [ ... ],
props: [ 'foo' ],
},
},
}); This way |
I ended stubbing the component locally: const ChildComponentStub = {
name: 'child-component',
template: '<div />',
props: [ 'foo' ],
};
describe('test ParentComponent', () => {
it('renders as expected', () => {
const wrapper = shallowMount(ParentComponent, {
stubs: {ChildComponent: ChildComponentStub}
});
expect(wrapper.find(ChildComponentStub).props('foo')).toBe(wrapper.vm.bar);
});
}); It works in the way I can test the value passed to the prop, but it won't catch if the |
So after thinking about it I wrote this helper function: // ./tests/helpers/create-stub.js
const extractProps = function extractProps(component, props) {
const results = Object.assign({}, props);
if (Array.isArray(component.mixins)) {
const reduced = component.mixins
.reduce((result, mixin) => Object.assign(result, extractProps(mixin, {})), {});
Object.assign(results, reduced);
}
if (component.props) {
if (Array.isArray(component.props)) {
const reduced = component.props
.reduce((result, prop) => Object.assign(result, {[prop]: {}}), {});
Object.assign(results, reduced);
} else {
Object.assign(results, component.props);
}
}
return results;
};
export default function createStub(name, component) {
return {
name,
props: extractProps(component, {}),
template: '<div />',
};
} I don't know if this is the best approach, and it would be useful to have something similar bundled in the If this is something desirable, I can try to send a PR, although it would be a fisrt-time contribution to the repo. |
shallowMount
: Stub child component props (explicit defined in componente or from mixin)
shallowMount
: Stub child component props (explicit defined in componente or from mixin)
I've done something similar not too long ago that, surprisingly, seems to work pretty great.
My test looks like this:
EDIT: I just checked and you can even do |
If you're stubbing the component because its lazily loaded, you can pass the actual component implementation directly as the stub instead of setting it to Before: const wrapper = shallowMount(ParentComponent, {
stubs: {
ChildComponent: true
},
}); After: import ChildComponent from '@/components/ChildComponent'
const wrapper = shallowMount(ParentComponent, {
stubs: {
ChildComponent: ChildComponent
},
}); |
What problem does this feature solve?
I faced this today when trying to test if a child component received a prop.
Unfortunately the child component defines this specific prop through a mixin, so using
shallowMount
doesn't let me assert using theprops()
helper:As the
props()
method returns an empty object, the assertion fails.For now I am testing like this
Note I cannot test the attribute value as
shallowMount
converts all attributes to string, so the value of the foo attribute becomes '[Object object]'Reading through #814, #814 and #965 it seems that when stubbing a component that doesn't have a property explicitly defined in the component, vue -test-utils doesn't count it as a prop.
The ideal was to the the stubbed component to have all properties, but I understand it can be hard to implement.
My proposal is to either add all attributes passed using v-bind on the template as props to a stubbed child component so we can test the value passed.
Or keep them as attributes but have their values formatted using
JSON.stringify
when using v-bind.What does the proposed API look like?
The text was updated successfully, but these errors were encountered: