Open rmartins90 opened 7 years ago
shallow
stubs every child components render functions and lifecycle events, and then mounts it.
shallow({
render: h => h('div', ComponentWithProps, { }, [
{
name: 'ChildComponent',
mounted() { console.log('mounted' },
render: h => h('p'),
props: {
prop1: true
}
}
])
})
will call mount
with this:
mount({
render: h => h('div', ComponentWithProps, { }, [
{
name: 'ChildComponent',
mounted: () => {},
render: () => {},
props: {
prop1: true
}
}
])
})
Maybe shallow
should stub other child properties? It's good to keep props so you can check the child component has props, but there might be other properties on the child component that cause errors like the one you're seeing.
Maybe it should stub watchers then? What about router-link component? If I use shallow router-link still requires router.resolve, shouldn't it be stubbed?
@rmartins90 Yes I think you're right
Maybe the default behavior should be to return a component with the minimal props required to identify it and test that it's been passed the correct propsData
.
@eddyerburgh I agree with @rmartins90. The shallow should allow us to skip all the dependencies of a child component, only testing high-level parent components.
Yep, I'll add this tonight
Ok, I've fixed this in 2.4.2
Thanks @eddyerburgh for the quick fix. Congrats on this library. I'll try it.
Thanks @eddyerburgh. Very well done. 👍
@eddyerburgh this still doesn't work for components that are not specified on components dict. For example, <router-link>
still tries to user resolve function (that is on router undefined object) if I use shallow. I think shallow should mock this components as well.
Global components?
I'll have a look into how best do this.
Yes, like <router-link>
component. I think every child component should be ignored in order to be able to do a more unitary test for a component, don't you agree? I don't think it'll be easy. By now I'm mocking them using your trick from https://github.com/eddyerburgh/avoriaz/issues/41 but I think it'll be more elegant if avoriaz shallow function could deal with this global components.
@rmartins90 yeah I agree, I'll implement it tomorrow 👍
@rmartins90 just to be clear, do you mean shallow
should overwrite any global component that has already been rendered. Or do you mean shallow
should stub every component referenced inside a template?
The first one I can implement tonight. The second one will take much longer.
I'm not even sure if it's doable without being prone to errors.
I think this will probably always be the approach for global components that aren't registered:
// mock component
const routerView = {
name: 'router-view',
render: h => h('div'),
};
// register mock component
Vue.component('router-view', routerView);
Or maybe as an improvement:
import { componentStub } from 'avoriaz'
// register mock component
Vue.component('router-view', componentStub)
@eddyerburgh You're right, the interesting feature would be stub every component referenced inside a template, but as I said previously it's not easy to implement. Your mock component solution works just fine for now.
shallow
now stubs every globally registered in 2.4.3
I am using shallow
to render my subject component which contains a child Modal
, this Modal contains a slot in which subject places another component, we'll say MyContent
. MyContent has props that subject is providing, but I don't seem to be able to test this because Modal
is not rendered as per the stubbing of it's render
function. How can I use shallow
and test that subject is correctly passing props to my "slotted" content? I have seen shallow>options.slots, but it is not clear to me from the docs if this is the correct place to go.
I think you can use mount for this, unless you think it's a bug. If it's a bug, can you post the component and test?
Yes, I could use mount, but I have another complex child component that is a sibling of my Modal
, so I don't want to render that. 2 options I see may be: (1) somehow provide a test interface to assert slots were configured properly, even if they are not actually rendered, or (2) in mount
options add a .blacklist [Component], or in shallow
options add .whitelist [Component] which would conditionally not-render/render the specified child components. This way, I could do something like shallow(MyPage, { whitelist: [Modal] })
. I could look at a PR if you think this a possibility
The option you've described where you can blacklist components sounds like the stub
option that
exits in vue-test-utils
(it's the currently unreleased official test library). You can pass it a template string, and it will replace the component you named with a stub:
const wrapper = mount(Component, {
stub: {
ComplexComponent: '<div />'
}
})
If I find the time in the next few weeks I will add it to avoriaz. In the meantime, if you feel up to it you could implement a PR using the code from vue-test-utils
.
The code is here - https://github.com/vuejs/vue-test-utils/blob/master/src/mount.js#L74 And the tests - https://github.com/vuejs/vue-test-utils/blob/master/test/integration/specs/mount/options/stub.spec.js
I will check vue-test-utils repo and try to make a PR on this.
Check it out #130 I think it could do the trick. This is valid for my case.
@eddyerburgh I could really use that stub option for mount/shallow. I am considering porting it to avoriaz or making the move to vue-test-utils to get it. Not sure which makes more sense. Curious how long you think it will be worthwhile to continue to port new features back here?
I think some people will be using this project for a long time, so porting this feature would be very useful for some people. I'd happily accept a PR that added the stubs option!
On Thu, Nov 30, 2017 at 8:15 PM, Scott Smith notifications@github.com wrote:
@eddyerburgh https://github.com/eddyerburgh I could really use that stub option for mount/shallow. I am considering porting it to avoriaz or making the move to vue-test-utils to get it. Not sure which makes more sense. Curious how long you think it will be worthwhile to continue to port new features back here?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/eddyerburgh/avoriaz/issues/75#issuecomment-348308120, or mute the thread https://github.com/notifications/unsubscribe-auth/AMlbW0J4uO9DOlRQSI0h3OCq2nV-1p0Uks5s7wzygaJpZM4OMU68 .
I started looking this and realized that I may actually want to build upon the renderDefaultSlot option that was added earlier by @disitec. Currently, that option applies only to global components. However, we struggle with wanting to test the default slot content for a child component while using shallow. If I understand things correctly, shallow stubs child components the same way that global components are stubbed, so would it be presumptuous to say that the renderDefaultSlot option could also apply to stubbed child components when using shallow?
Let me know what you think and if we are on agreement, I can work on this update.
@scottadamsmith yes if you'd like to implement I'd be happy to review and merge 🙂
Start to ask if you can detail the shallow and mount differences in documentation, it would be great to know exactly what to expect.
I'm getting what I think could be a bug, or something that I'm missing. For the given test, component and result:
Component:
Test:
Error:
Popover component has a watcher on triggerElements prop.
If I replace shallow by mount everything works just fine.