How to write test that mocks the $route object in vue components

Jerry Zhang picture Jerry Zhang · Jan 4, 2017 · Viewed 24.1k times · Source

I have a component that contains statement like this.$route.fullPath, how should I mock value of fullPathof $route object if I want to test that component?

Answer

SColvin picture SColvin · Jan 8, 2017

Best not mock vue-router but rather use it to render the component, that way you get a proper working router. Example:

import Vue from 'vue'
import VueRouter from 'vue-router'
import totest from 'src/components/totest'

describe('totest.vue', () => {
  it('should totest renders stuff', done => {
    Vue.use(VueRouter)
    const router = new VueRouter({routes: [
        {path: '/totest/:id', name: 'totest', component: totest},
        {path: '/wherever', name: 'another_component', component: {render: h => '-'}},
    ]})
    const vm = new Vue({
      el: document.createElement('div'),
      router: router,
      render: h => h('router-view')
    })
    router.push({name: 'totest', params: {id: 123}})
    Vue.nextTick(() => {
      console.log('html:', vm.$el)
      expect(vm.$el.querySelector('h2').textContent).to.equal('Fred Bloggs')
      done()
    })
  })
})

Things to note:

  1. I'm using the runtime-only version of vue, hence render: h => h('router-view').
  2. I'm only testing the totest component, but others might be required if they're referenced by totest eg. another_component in this example.
  3. You need nextTick for the HTML to have rendered before you can look at it/test it.

One of the problems is that most of the examples I found referred to the old version of vue-router, see the migrations docs, eg. some examples use router.go() which now doesn't work.