I am trying to test a vue component that displays a google map
The google include script element is somewhere in a parent component and the component I am trying to test gets is reference to it globally:
const googleInstance = window.google
My alarm bells rang when I saw it is global, but its the code I have been given and I need to get my coverage higher!
The code in the component gets the instance here:
this.map = new googleInstance.maps.Map(mapElement, this.options)
I get many errors starting with:
TypeError: Cannot read property 'maps' of undefined
I have tried adding googleInstance and google to the mocks parameter when shallow mounting the wrapper
const wrapper = shallowMount(Map, {
mocks: {
google: {
maps: () => {}
}
}
})
Neither worked and I get the same response:
TypeError: Cannot read property 'maps' of undefined
I tried:
global.google = {
maps: () => {}
}
That did not work either
Here is a simplified version of the map component that I am trying to test:
<template>
<div>
<div refs="mapLayer" :id="mapName" class="mapLayer" />
</div>
</template>
<script>
const googleGlobal = window.google
export default {
name: 'Map',
props: {
name: {
type: String,
required: true
}
},
mounted () {
this.initMap()
},
methods: {
initMap () {
const mapElement = document.getElementById(this.mapName)
this.map = new googleGlobal.maps.Map(mapElement)
}
}
}
</script>
The code has been refactored and previously the google instance came via the Vuex store and my tests worked
My other thought was to return googleInstance from a separate file, which I could then mock using jest, but ultimately that just moves the problem to another file that would still be untestable
How can I mock the values in my component or how could the code be refactored to be testable?
The problem is that your const googleGlobal = window.google
sentence is being executed before you introduce the mock in the test file.
Because of this, the googleGlobal
constant is equal to undefined
. A solution for this could be to define a method in your component that returns the global variable google
, and obtain the reference by calling this method.
<script>
export default {
name: 'Map',
props: {
name: {
type: String,
required: true
}
},
mounted () {
this.initMap()
},
methods: {
getGoogle() {
return window.google
},
initMap () {
const googleGlobal = this.getGoogle()
const mapElement = document.getElementById(this.mapName)
this.map = new googleGlobal.maps.Map(mapElement)
}
}
}
</script>
Then, in your test file you can mock window.google
like:
window.google = {
maps: { Map: function() {} }
}
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