Vue-test-utils: Unable to mock properties with only getters, such as $route

Created on 1 Nov 2017  ·  6Comments  ·  Source: vuejs/vue-test-utils

Version

1.0.0-beta.2

Reproduction link

https://github.com/tbeadle/vue-mock-issue

Steps to reproduce

Clone the repo at https://github.com/tbeadle/vue-mock-issue and run yarn run unit.

What is expected?

The $route property should be able to be mocked, as documented in the "Stubbing global properties" section of https://vue-test-utils.vuejs.org/en/api/mount.html

What is actually happening?

The call to mount fails because of the error: setting a property that has only a getter.


I have a component that uses $route.query during its created function, so I need to mock it to unit test that functionality, to make sure that the component is rendered correctly. That's when I ran in to this problem.

discussion

Most helpful comment

There's a section in the docs, in common gotchas — https://vue-test-utils.vuejs.org/en/guides/using-with-vue-router.html

I'd welcome any improvements

All 6 comments

This is an ongoing issue.

Installing Vue Router adds $route as a read only property on the base Vue constructor. This means there's no way to overwrite the property in further tests. You can see some discussion on the issue here —https://github.com/vuejs/vue-router/issues/1768

One thing we can do is to throw an error with more information on why the mock was unsuccessful.

Something like this:

[vue-test-utils]: Unable to mock property $route. The $route property is installed as a read only property. You might have installed a plugin in earlier tests that added this property.

If this is not going to get resolved (soon), we should add a section in the documentation about this.

In the tests where one would want to mock the router, they get a clean Vue via createLocalVue() and then do not apply Vue.use(VueRouter). This way the $route and $router objects can be mocked without the error.

There's a section in the docs, in common gotchas — https://vue-test-utils.vuejs.org/en/guides/using-with-vue-router.html

I'd welcome any improvements

@eddyerburgh How can I fix this problem without remove installing global Vue instance from codes?
Since this is a historical issue in our project, I can't remove the all codes about 'Vue.install(VueRouter)' in a short time.

Unfortunately there isn't a way to overwrite once you've installed.

All you can do is seperate out Vue.use(VueRouter) from the code you test. You should only be calling it once in your app, normally in your entry file.

I'm going to close this issue, even though it's ongoing.

There's nothing we can do in vue-test-utils to overwrite properties that are set as read only with defineProperty.

If you have problems with a library adding properties as read only, you can make an issue with that library.

There is an issue open in vue-router to make $route and $router writable — https://github.com/vuejs/vue-router/issues/1768

Was this page helpful?
0 / 5 - 0 ratings