Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vue-test-utils: mocking vue-router and vuex in the same test

I'm trying to mount a component that uses Vuex and requires $route.query to be mocked

import { mount, shallow, createLocalVue } from 'vue-test-utils'
import Vue from 'vue'
import expect from 'expect'
import Vuex from 'vuex'
import VueRouter from 'vue-router'

import Post from '../../components/Post.vue'

const localVue = createLocalVue()

localVue.use(Vuex);
localVue.use(VueRouter);

describe('Lead list', () => {
    let wrapper;
    let getters;
    let store;

    beforeEach(() => {

        getters = {
            post: () => { return {} }
        }
        store = new Vuex.Store({
            getters
        });

    });


    it('should just be true', () => {

        const $route = {
            path: '/some/path',
            query: {}
        }

        wrapper = shallow(Post, {
            localVue,
            mocks: {
                $route
            }, store
        });

        expect(true).toBe(true);

    });
});

And I'm getting back this error

TypeError: Cannot set property $route of #<VueComponent> which has only a getter

I've found the closed issue https://github.com/vuejs/vue-test-utils/issues/142 that has similar error. But my case is a little different. If I remove store or mocks from the options it works fine, but it does't work when you have both. Is this an issue or I'm doing something wrong?

Thanks

like image 762
meoweloper Avatar asked Jan 29 '23 04:01

meoweloper


1 Answers

You're getting this error because you have installed VueRouter on the Vue constructor, by calling localVue.use(VueRouter). This adds $route as a read only property on the localVue constructor.

You're then trying to overwrite $router using mocks. mocks is unable to overwrite $route because it's been added as a read only property by Vue Router.

To fix your problem, you could create another localVue, install Vuex, and then use mocks to pass in $route:

it('should just be true', () => {
  const freshLocalVue = createLocalVue()
  freshLocalVue.use(Vuex)
  const $route = {
    path: '/some/path',
    query: {}
  }

  wrapper = shallow(Post, {
      localVue,
      mocks: {
          $route
      }, 
      store
  })

  expect(true).toBe(true)
})
like image 120
Edward Avatar answered Feb 05 '23 14:02

Edward