Search code examples
unit-testingvuejs2axiosavoriazmoxios

Avoid vue warnings when mocking router in vue.js tests


I'm testing a Vue.js 2 application which uses Axios for HTTP requests and I am mocking these requests with Moxios. The test uses Avoriaz as well.

The page I am testing just renders a list of elements and displays some buttons which are implemented using <router-link>

The problem is that I get a lot of warnings in my tests in the style of

ERROR LOG: '[Vue warn]: Unknown custom element: <router-link> - did you register the component correctly?

My page I want to test looks like this (simplified):

<template>
<div>
  <ul>
    <li v-for="myelement in myobject.myelements">
        {{myelement.id}}
    </li>
  </ul>
  <router-link :to="{name: 'myElementCreate'}">New element</router-link>
</div>
</template>
<script>
import myService from './my-service.js'

export default {
  name: 'my-list',
  data() {
    return {
      myobject: {
        myelements: []
      }
    }
  },
  created() {
    this.fetchData()
  },
  methods: {
    fetchData() {
      if (this.$route.params.id) {
        myService.get(this.$route.params.id)
          .then((response) => {
            // init data from response
          })
      }
    }
  }
}
</script>

The test looks like this:

import Vue from 'vue'
import moxios from 'moxios'
import {shallow} from 'avoriaz'
import MyElements from '@/my-elements'

describe('My Elements', () => {
  beforeEach(() => {
    moxios.install()
  })

  afterEach(() => {
    moxios.uninstall()
  })

  it('Renders elements list', (done) => {
    moxios.stubRequest(/.*/, {
      status: 200,
      response: existingElement
    })

    // mock route to allow fetchData() to load elements
    const component = shallow(MyElements, {
      globals: {
        $route: {params: {'id': 1}}
      }
    })

    moxios.wait(() => {
      Vue.nextTick(() => {
        try {
          const myElement = component.find('ul li')
          expect(myElement[0].text()).to.equal('6035132')
        } catch (e) {
          done(e)
        }
        done()
      })
    })
  })
})

const existingElement = {
  'id': 6035132
}

If I add Vue.use(Router) and the according import, the warnings are gone but my Moxios mock won't work any more. Any idea how to get rid of these warnings?


Solution

  • The problem is that router-link is not registered as a component.

    If you don't install Vue Router, the router-link component is not registered. That means it can't be used in your component.

    To fix this, you can register a stub router-link component:

    // mock component
    Vue.component('router-link', {
      name: 'router-link',
      render: h => h('div')
    })
    
    const component = shallow(MyElements, {
      globals: {
        $route: {params: {'id': 1}}
      }
    })