2 min read

Quasar unit test with vitest - Router mock and router-link

Quasar unit test with vitest - Router mock and router-link
Quasar logo https://quasar.dev

Perhaps you have come across a warning in the console when running the tests.

injection "Symbol([vue-router]: router)" not found. 

# or

[Vue warn]: Failed to resolve component: router-link

These 2 warnings are due to the fact that in the tests the vue-router is not available and we must tell the test suite that this exists.

We will first solve the use of the router link tag, the @vue/test-utils package includes an object called RouterLinkStub that helps us solve this problem without much effort.

import { describe, it, expect } from 'vitest'
import { mount, RouterLinkStub } from '@vue/test-utils' // The RouterLinkStub import
import { Quasar } from 'quasar'

import NoIntegrationsAction from "../../src/components/Integrations/NoIntegrationsAction.vue";

const wrapperFactory = () => mount(NoIntegrationsAction, {
  global: {
    plugins: [Quasar],
    mocks: {
      $t: (msg) => msg
    },
    stubs: {
      RouterLink: RouterLinkStub // Use here of the RouterLinkStub
    }
  },
})

const wrapper = wrapperFactory();

describe('No integrations action component', () => {
  it('mount component', () => {
    expect(NoIntegrationsAction).toBeTruthy();
  })

  it('should be have a text', () => {
    expect(wrapper.text()).toContain('messages.information.noIntegration1');
    expect(wrapper.text()).toContain('messages.information.noIntegration2');
    expect(wrapper.text()).toContain('action.clickHere');
  })

  it('should be have a link', () => {
    const link = wrapper.find('a'); // Here an example
    expect(link.exists()).toBe(true);
  })

})
Example: https://github.com/ta-vivo/ta-vivo/blob/master/tests/integrations/NoIntegrationsAction.test.js

This basically converts all router-link tags into HTML a tags.

Router not found

This warning is due to the fact that the router package is not available inside the tests and that is why it is not possible to use the useRouter, for this case we need to create a mock inside /test/mocks we will create the file router.js

import { vi } from 'vitest'

vi.mock('vue-router', () => ({
  useRouter: () => ({
    push: vi.fn(),
    replace: vi.fn(),
    go: vi.fn(),
    back: vi.fn()
  }),
  useRoute: () => ({
    path: vi.fn(),
    params: vi.fn(),
    query: vi.fn(),
    fullPath: vi.fn(),
    hash: vi.fn(),
    matched: vi.fn(),
    name: vi.fn()
  })
}))

Now that we have our mock we just need to import it into our test files.

import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { Quasar } from 'quasar'
import $q from '../mocks/Quasar'
import '../mocks/router' // The new mock, no extra stuff to do

// The test code
Example: https://github.com/ta-vivo/ta-vivo/blob/master/tests/interface/DesktopMenu.test.js