-
Notifications
You must be signed in to change notification settings - Fork 668
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
Mock $parent when mounting/shallow a component #560
Comments
I'll upvote this request. Been trying to figure out how to achieve the same thing. Being able to mock $parent would be appreciated. Are there any possible workarounds in the meantime? |
Since beta.18 every mounted component has a $parent defined. I can't think of any workarounds for mocking it currently, but I'll look into adding it as a feature. |
@Mweydert @jpicton How would you like to mock the parent? Would you imagine passing a component as a parent? In this case the template would need to be overwritten: const Parent = {
data: () => ({
val: true
}),
template: '<div />'
}
const wrapper = shallowMount(TestComponent, {
parent: Parent
}) Alternatively we could support a custom string/component that will be replaced by the component that should be rendered (although this will be more difficult): const Parent = {
data: () => ({
val: true
}),
template: '<div><TEST_COMPONENT /></div>'
}
const wrapper = shallowMount(TestComponent, {
parent: Parent
}) |
@eddyerburgh I am not sure to understand what you mean here. If I should mock the parent of a component, I would intuitively try to pass my component "Parent" in a prop 'parent' of mounting options; as in your first example. For your second proposition, what I understand is that you propose to set a custom string in "parent" mounting option. For example: const wrapper = shallowMount(TestComponent, {
parent: '<my-parent></my-parent>'
}) would create a fake component 'my-parent' and then link it to the wrapper? Thanks for your propositions. |
@eddyerburgh using the parentComponent option, if we provide a component that itself also has a parent component defined, should the first component be able to access the this.$parent.$parent property? I'm having trouble getting this to work: let parentParentWrapper = mount(MeasureSelection);
let parentComponentStub = {
name:"parentStub",
template:'<div></div>'
};
let parentWrapper = mount(parentComponentStub,{
sync:false,
parentComponent:parentParentWrapper.vm
});
let desiredWrapper = mount(SomeOtherComponent,{
sync:false,
parentComponent:parentWrapper
}); and then in the |
No we've only written the parent API to work with a single component, if you'd like to see this feature then feel free to open a feature request :) |
Ok, happy to open a feature request, but for the moment, is there any way to setup this test such that I can fake a $parent.$parent property? |
@eddyerburgh also, thanks for writing Testing Vue.js Applications, a worthwhile purchase for sure! |
You could do something like this: const GrandParentVm = mount({
template: '<div />',
data() {
return { val: 1 }
}
}).vm
const Parent = {
created() {
this.$parent = GrandParentVm
}
}
const TestComponent = {
template: '<div />',
mounted() {
console.log('parent', this.$parent.$parent.val)
}
}
const wrapper = mount(TestComponent, {
parentComponent: Parent
}) |
Yes!!! It works!!! Thank you so much, this was driving me crazy, and keeping me from finishing the last few tests in my suite, thanks again! |
What's the alternative to accomplishing this on Vue 3 / Vue Test Utils 2 since |
What problem does this feature solve?
Enable a component that calls a method of its parent (for example this.$parent.$emit) in the "mounted" hook to be shallowed or mounted without any issue.
Use case:
I have a component ("VueDetail.vue") that is mounted by a third party library (let's name the main component ThirdParty.vue). I can't listen for the events emitted by VueDetail.vue as I don't instantiate the component myself (instanciated by ThirdParty.vue, therefore event should be handled in ThirdParty.vue).
As an alternative, I decided to emit an event from VueDetail's parent (i.e. call this.$parent.$emit("my-event") in VueDetail.vue). By doing that, the event is emited from ThirdParty.vue and I can handle this event in my component that mount ThirdParty.vue.
A consequence is that I need to mock the wrapper's parent (this.$parent or wrapper.vm.$parent in tests). I achieve doing so pretty easily by shallowing a second component and define it as the parent of the component I am testing.
Here comes the tricky part: I now want to call this.$parent.$emit from the "mounted" hook of VueDetail.
My code run as expected, but all my tests break. All my tests failed when executing the "mounted" hook because this.$parent is not defined at the moment.
Indeed there is no mean (or at least not I am aware of) to mock $parent WHEN mounting a wrapper.
What does the proposed API look like?
I know it is already possible to add additional property to the instance using the mocks property. I think this could be used for the feature I proposed.
Thanks for the library !
Michael
The text was updated successfully, but these errors were encountered: