THE SITUATION
I am trying to shallowMount
a component, unsuccessfully.
The component makes use of $refs
to read the height of a div
. That value is read inside a computed 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 component breaks, because the $refs
key is undefined
.
To be clear: I don't intend to test the $refs
, I just need to mount the component 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 computed property:
computed: {
barH() {
return this.$refs.tgmp.clientHeight
}
}
And then, in the mounted lifecycle, I commit the value in the store:
this.$store.commit('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 component that makes us of $refs
in the mounted
lifecycle?
Referencing DOM Elements in Vue # Vue can store references to DOM elements in a property called $ref . The first thing we have to do, is add a ref attribute to the element we want to reference in our Javascript. The value of the ref attribute will be the name of it within the $ref property.
$refs...are not reactive. However, I have used such refs in templates and they are indeed reactive, and even in methods, computed props, and watchers (as long as you access it after being mounted). Several third party vue libraries e.g. this one also provides features that use/depend on the reactivity of refs.
Vue Test Utils is the official unit testing utility library for Vue. js. This is the documentation for Vue Test Utils v1, which targets Vue 2 and earlier.
$refs is undefined when the element with the ref attribute is not visable at the moment you use the this. $refs object. This costs me some time to figure out. It has a button that opens a div that contains an input field with a ref attribute.
shallowMount
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 component initialization. It's computed 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.computed, 'barH').mockReturnValue(600);
Or:
wrapper = shallowMount(Bar, {
store,
computed: { barH: () => 600 }
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With