Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vue-test-utils: could not overwrite property $route, this is usually caused by a plugin that has added the property as a read-only value

I've looked at other answers with this problem, and it seems to be caused by trying to import vue-router into the test. This however, is not the case for my problem. Here is my test code:

import { mount, shallowMount, createLocalVue } from '@vue/test-utils'
import ListDetails from '../components/homepage/ListDetails'
import EntityList from '../components/homepage/EntityList'
import BootstrapVue from 'bootstrap-vue'
import Vuex from 'vuex'
import faker from 'faker'

const localVue = createLocalVue()

localVue.use(Vuex)
localVue.use(BootstrapVue)

describe('ListDetails.vue', () => {
    it('gets the correct page list when router list id param present', () => {
        const selected_list = {
            id: faker.random.number(),
            name: faker.lorem.words(),
            entries: []
        }

        testRouteListIdParam(selected_list)
    })
})

Then in testRouteListIdParam, I have:

function testRouteListIdParam(selected_list) {
    // just assume this sets up a mocked store properly.
    const store = setUpStore(selected_list, true)

    const $route = {
        path: `/homepage/lists/${selected_list.id}`
    }

    const wrapper = mount(ListDetails, {
        mocks: {
            $route
        },
        store,
        localVue
    })
}

As soon as mount() happens, I get the error:

[vue-test-utils]: could not overwrite property $route, this is usually caused by a plugin that has added the property as a read-only value

Any ideas why this would be happening? Again, I'm not using VueRouter anywhere in the unit tests, so I'm not sure why I'm getting the error. Could it be BootstrapVue or Vuex that are messing things up?

like image 507
janedoe Avatar asked Apr 04 '19 19:04

janedoe


People also ask

Could not overwrite property $Route This is usually caused by a plugin?

This means any future tests that try to mock $route or $router will fail. To avoid this, never install Vue Router globally when you're running tests; use a localVue as detailed above. The error you're seeing indicates that one of your components (and outside your test code) is installing VueRouter (e.g., Vue.

What is VUE test utils?

Vue Test Utils is the official unit testing utility library for Vue. js. This is the documentation for Vue Test Utils v1, which targets Vue 2 and earlier.

Why VUE-test-utils could not overwrite property $route?

console.error [vue-test-utils]: could not overwrite property $route, this is usually caused by a plugin that has added the property as a read-only value appears. Actually, what I truly wanna do is not to mock route but to use real router but there is another issue.. If you know the solutions for these issues, please let me know!

What happens when installing vue router on a Vue prototype?

Installing Vue Router adds $route and $router as read-only properties on Vue prototype. This means any future tests that try to mock $route or $router will fail.

Why can't I install vuerouter when running tests?

To avoid this, never install Vue Router globally when you're running tests; use a localVue as detailed above. The error you're seeing indicates that one of your components (and outside your test code) is installing VueRouter (e.g., Vue.use (VueRouter) ).


3 Answers

So this is a bug with vue-test-utils. If you are using VueRouter anywhere (even if it's not used in any unit test), you will get the above error.

A work around is to use process.env.NODE_ENV in your unit tests and set it to 'test', and wherever you're using VueRouter, check process.env.NODE_ENV like so:

if (!process || process.env.NODE_ENV !== 'test') {
    Vue.use(VueRouter)
}

at least until vue-test-utils bug is fixed, this should fix this problem

like image 102
janedoe Avatar answered Oct 23 '22 13:10

janedoe


I think these docs are relevant to your situation:

Common gotchas

Installing Vue Router adds $route and $router as read-only properties on Vue prototype.

This means any future tests that try to mock $route or $router will fail.

To avoid this, never install Vue Router globally when you're running tests; use a localVue as detailed above.

The error you're seeing indicates that one of your components (and outside your test code) is installing VueRouter (e.g., Vue.use(VueRouter)).

To address the issue, search for the VueRouter installation in your component code path, including any of their imports, and refactor it so that the import is not required there. Typically, the installation of VueRouter exists only in main.js or its imports.

GitHub demo

like image 35
tony19 Avatar answered Oct 23 '22 13:10

tony19


I encountered this, and it was because I was importing vueRouter into a controller, outside of a vueComponent, where this.$router wasn't defined.

import router from '@/router';
router.push('/foo')
like image 40
Christa Powers Avatar answered Oct 23 '22 14:10

Christa Powers