-
Notifications
You must be signed in to change notification settings - Fork 669
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
Automatically stub nested components with their names instead of <!---->
#410
Comments
This is a great idea! We could make it an option, and also have it as an option you can set in the config, so you only need to set it once: VueTestUtils.config.shallowStubsAsText = true Would you like to add a PR? I'm happy to if you're not able to By the way, are you aware you can check a component has been rendered with shallow? import MyCustomComponent from '~/MyCustomComponent.vue'
const wrapper = shallow(TestComponent)
wrapper.find(MyCustomComponent).exists() This is sort of a clone of #28. When we add this feature, we can close #28 |
Sadly, I have too much on my hands atm to make a PR. I was unaware that you can check if a component is included that way, but I think the text stubs will still help when you’re debugging stuff (logging out wrapper.html()) and it will make it a generally more streamlined experience. Thanks for a quick response! :) |
Actually, I think I'll look into it. Have some more time this week. Shouldn't be that complicated |
So, yeah, that took more than a week :) I played around with the concept, and I'm a bit concerned about all the warnings in the console about using non-registered components with an approach like that. Was unable to get around them. I will try to make a PR sometime this week, so maybe someone else can take a look as well. |
This feature will be useful for snapshot testing also. |
Hey @ilyaztsv you want me to share my current solution? The above is a set of handy utils I use to have better time testing. This approach drops a lot of warnings about "unregistered components", but if those are not a big deal for you - this setup works quite well. I was emulating the way shallow rendering works in |
@orels1 You can ignore custom elements by adding them to the ignoredElements array—https://vuejs.org/v2/api/#ignoredElements. That should stop warnings |
@orels1 thanks for your solution. I'll try it with |
@orels1 @eddyerburgh Unfortunately, "stub-generator" solution does not work for me. May be because of I use jest + vue-test-utils. |
@ilyaztsv my solution uses |
I've written a stub generator that works with jest and vue-test-utils: export function generateStubs(cmp) {
return Object.values(cmp.components).reduce((stubs, stubCmp) => {
const dashName = stubCmp.name
.replace(/([a-z])([A-Z])/g, '$1-$2')
.toLowerCase();
stubs[dashName] = {
render(createElement) {
return createElement(dashName, this.$slots.default);
},
};
return stubs;
}, {});
} This requires all components to have their Use it like this: // components
export default {
name: 'MyComponent',
components: {
FooBar,
},
}
export default {
name: 'FooBar',
}
// test
const component = shallow(MyComponent, {
stubs: generateStubs(MyComponent),
}); |
@AlbertBrand unfortunately, it is still cause you can see #465 for more details. |
@ilyaztsv Interesting, I tried some things in your repo and found the issue. If you change line 13 in |
@AlbertBrand thanks for the reply! It did help :) |
Seems like it also possible to auto-generate stubs when registering plugin like Vuetify. |
@AlbertBrand Thanks for sharing your tips. Unfortunately, #410 (comment) did not work in my environment while components for typescript user is wrapped with So I modified it as below and works well. In case someone faced the same problem. export function generateStubs(component: any) {
const children = component instanceof Function
? component.extendOptions.components
: component.components;
const reducer = (accumulator: {[key: string]: any}, value: string) => {
const lhs = value[0];
const rhs = value.substr(1);
const name = (lhs + rhs.replace(/([A-Z])/g, '-$1')).toLowerCase();
accumulator[name] = {
render(createElement) {
return createElement(name, this.$slots.default);
},
};
return accumulator;
};
return !!children ? Object.keys(children).reduce(reducer, {}) : undefined;
} Tested with
|
Unfortunately, above stub seal events, attributes, or etc so it is really difficult to test the behavior. |
Is someone working on this actually? |
Not currently. If you'd like to work on it, I would be happy to review a PR :) |
@AlbertBrand 's solution looks well to me. |
I personally have been using a generalized mock-component that just displays a fake element and renders all its slots and children and most of the props and attrs as normal DOM attributes and it works quite well for snapshots when used in combination with Here is the gist Maybe it's helpful for someone |
I've made a PR: #606 |
What problem does this feature solve?
In my workflow it is a pretty common use case to have a unit test that checks if some nested component is being rendered conditionally.
For example i have a component with a template like this (I use pug for templating, just so there won't be any confusion):
And I want to have a unit test that makes sure that
MyCustomComponent
is only rendered when that condition is satisfied.I'm coming from React background, where
enzyme
's shallow render passes component's display name by default. So if I would shallow render the setup above - thewrapper.html()
would look something like this (if thev-if
condition was met):But in
vue-test-utils
the result would actually look like this:There is currently an option to supply a stubs object to
shallow
render method, but that requires you to manually write a list of components and their respective stubs, which is not time-efficient.Currently I wrote a simple stub-generator, which acts somewhat like identity-object-proxy, and basically looks at the list of
components
in options of the component we want to render, and generates an object of stubs.That allows me to achieve a result like this:
Which is basically what I need.
I can see more people that might want this kind of behaviour to speed up the unit testing, as this is a pretty common approach in other systems.
My stubs generator code for context:
Pretty basic, but it allows me to simply use
wrapper.find('<component name>');
to conditionally check if something was rendered, without manually supplying the stubs object every time, since I have a custom wrapper aroundshallow
that passes my generator to thestubs
option.What does the proposed API look like?
I'm not sure if this should be the default behaviour, since people might rely on current way of stubbing in the existing code, but I can see something like a flag "useNamedStubs" for
shallow
options, or something similar.The text was updated successfully, but these errors were encountered: