THE SITUATION
I am trying to shallowMount
a ponent, unsuccessfully.
The ponent makes use of $refs
to read the height of a div
. That value is read inside a puted property. Then in the mounted
lifecycle I save that value in the store.
The logic itself is simple and works fine. But in the test suite, the mounting of the ponent breaks, because the $refs
key is undefined
.
To be clear: I don't intend to test the $refs
, I just need to mount the ponent and move on doing actual unit-testing.
THE COMPONENT
This is the markup:
<div ref="tgmp">
I save the height of the div in a puted property:
puted: {
barH() {
return this.$refs.tgmp.clientHeight
}
}
And then, in the mounted lifecycle, I mit the value in the store:
this.$storemit('setBarHeight', this.barH)
THE TEST
This is the test. I have omitted irrelevant stuff, like installing the store in the localVue.
beforeEach(() => {
wrapper = shallowMount(Bar, {
store,
})
})
test('is a Vue instance', () => {
expect(wrapper.isVueInstance()).toBeTruthy()
})
THE ERROR
Error in mounted hook: "TypeError: Cannot read property 'clientHeight' of undefined"
ATTEMPT
I have been trying searching anywhere for a solution, but couldn't find it. I have tried to mock the $refs, but without success:
wrapper = shallowMount(ThePlayerBar, {
store,
mocks: {
$refs: {
tgmp: {
clientHeight: 600
}
}
}
})
THE QUESTION
How can I mount a ponent that makes us of $refs
in the mounted
lifecycle?
THE SITUATION
I am trying to shallowMount
a ponent, unsuccessfully.
The ponent makes use of $refs
to read the height of a div
. That value is read inside a puted property. Then in the mounted
lifecycle I save that value in the store.
The logic itself is simple and works fine. But in the test suite, the mounting of the ponent breaks, because the $refs
key is undefined
.
To be clear: I don't intend to test the $refs
, I just need to mount the ponent and move on doing actual unit-testing.
THE COMPONENT
This is the markup:
<div ref="tgmp">
I save the height of the div in a puted property:
puted: {
barH() {
return this.$refs.tgmp.clientHeight
}
}
And then, in the mounted lifecycle, I mit the value in the store:
this.$store.mit('setBarHeight', this.barH)
THE TEST
This is the test. I have omitted irrelevant stuff, like installing the store in the localVue.
beforeEach(() => {
wrapper = shallowMount(Bar, {
store,
})
})
test('is a Vue instance', () => {
expect(wrapper.isVueInstance()).toBeTruthy()
})
THE ERROR
Error in mounted hook: "TypeError: Cannot read property 'clientHeight' of undefined"
ATTEMPT
I have been trying searching anywhere for a solution, but couldn't find it. I have tried to mock the $refs, but without success:
wrapper = shallowMount(ThePlayerBar, {
store,
mocks: {
$refs: {
tgmp: {
clientHeight: 600
}
}
}
})
THE QUESTION
How can I mount a ponent that makes us of $refs
in the mounted
lifecycle?
-
I'm not sure what's going on with refs in shallowMount, but you can try
mount
with specific stubs or mock a puted. – Estus Flask Commented Apr 15, 2020 at 9:42 - @EstusFlask thanks for replying! It seems it's working. I will make some more stuff to be sure of it. If you want you can reply since it seems the correct solution. – FrancescoMussi Commented Apr 15, 2020 at 10:06
-
I checked it and I'd expect a ref to be there in your case. Probably
<div ref="tgmp">
doesn't exist when you render it, could be if it's a child of other ponent or affected by a directive. – Estus Flask Commented Apr 15, 2020 at 11:12
1 Answer
Reset to default 9shallowMount
is supposed to provide refs, so this.$refs.tgmp
should be <div>
element in case <div ref="tgmp">
exists in the view on initial render.
$refs
isn't supposed to be mocked because it's internal property and assigned on ponent initialization. It's puted property that relies on a ref, so it can be mocked if necessary because element height is expected to be 0 in JSDOM:
jest.spyOn(ThePlayerBar.options.puted, 'barH').mockReturnValue(600);
Or:
wrapper = shallowMount(Bar, {
store,
puted: { barH: () => 600 }
})