Search code examples
vue.jsgoogle-analyticsvuejs2jestjsvue-test-utils

Can't Test Vue Component because Vue instance not defined


I have a Vue application that uses used Vue Analytics, which creates a this.$ga.page method to do page tracking. Now, I need to test my component, using Jest, but it says this.$ga.page is not defined. I'm initializing Vue Analytics in main.js.

How do I include main.js before the component in the test file? I know we need to add this in a beforeEach method, but I don't know exactly how to do that.

Vue Analytics init in main.js

import VueAnalytics from 'vue-analytics'

Vue.use(VueAnalytics, {
  id: 'UA-150437966-1'
})

My Homepage test

import { mount } from '@vue/test-utils'
import Homepage from '../../src/Pages/Homepage'


describe('Homepage', () => {
    const wrapper = mount(Homepage)

    it('has a button', () => {
        expect(wrapper.contains('button')).toBe(true)
    })
})

Homepage.vue excerpt

created: function() {
    //analytics

    this.$ga.page({
      page: "/",
      title: "Home page",
      location: window.location.href
    });
  }
};

Error I'm getting

Homepage › encountered a declaration exception

    TypeError: Cannot read property 'page' of undefined

      67 |     //analytics
      68 | 
    > 69 |     this.$ga.page({

Solution

  • Vue Test Utils recommends setting up your plugins in a localVue to avoid polluting the global Vue. This is what it would look like:

    import { localVue, mount } from '@vue/test-utils'
    import Homepage from '@/components/Homepage'
    
    localVue.use(VueAnalytics, { id: 'UA-150437966-1' })
    
    describe('Homepage', () => {
      let wrapper = null
    
      beforeEach(() => {
        wrapper = mount(Homepage, {
          localVue,
        })
      })
    
      // ...
    })
    
    

    On the other hand, if it doesn't matter in your tests that the global Vue is modified, you could setup your Jest 23.x environment with setupTestFrameworkScriptFile:

    // jest.config.js
    module.exports = {
      setupTestFrameworkScriptFile: '<rootDir>/tests/jest-setup.js',
    }
    

    And in your setup file, you could initialize Vue Analytics:

    // <rootDir>/tests/jest-setup.js
    import Vue from 'vue'
    import VueAnalytics from 'vue-analytics'
    
    Vue.use(VueAnalytics, {
      id: 'UA-150437966-1'
    })