- The issue: components
beforeMount
hook is called once when the component is rendered (this is expected), and for the second time when route is updated, but still points to the same component:- We start with
/
- We go to the
/user/1/post1
(points to the component with children) - The
beforeMount
is called - We go to the
/user/1/post2
(points to the same component)
- We start with
- Problem: the
beforeMount
is called again- This only happens in tests, not in the real app
- This works in v1.0.0-beta.29, but fails in v1.0.0-beta.30 and up
- The issue is only reproduced when we use
Vue.extend
to define the component (or with class-based components) - Breaking change: this commit, changes with
_Ctor = {}
assignments.
There is an issue with vue test utils beta 30 and up: when there are nested components and we use Vue.extend
to defined components.
The failing test passes successfully in beta 29, but fails in beta 30:
$ npm install @vue/[email protected]
+ @vue/[email protected]
$ npm run test:unit
...
router.push
beforeMount App
[!] beforeMount Parent
beforeMount Nested
beforeRouteUpdate Parent
beforeRouteUpdate Nested
✓ calls beforeMount only once
2 passing (48ms)
MOCHA Tests completed successfully
Now, install and run with beta 30:
$ npm install @vue/[email protected]
+ @vue/[email protected]
$ npm run test:unit
...
MOCHA Testing...
router.push
beforeMount App
[!] beforeMount Parent
beforeMount Nested
beforeRouteUpdate Parent
beforeRouteUpdate Nested
[!] beforeMount Parent
beforeMount Nested
1) calls beforeMount only once
1 failing
1) router.push
calls beforeMount only once:
AssertionError: expected 2 to equal 1
+ expected - actual
-2
+1
at Context.it (dist/js/webpack:/tests/unit/router.spec.js:83:1)
at process._tickCallback (internal/process/next_tick.js:68:7)
The issue was introduced by this commit, changes with _Ctor = {}
assignments.
If these assignments are commented out, the tests starts working.
It also works if we don't use Vue.extend
to define the component:
...
{
path: "/user/:id",
// It works, if we don't use Vue.extend.
component: {
// component: Vue.extend({
// Component with children, nested router-view.
render: function (h) {
return h("router-view");
},
...
And Vue.extend
is needed for typescript-based setup, to have the typing working for components (also, I am actually using vue class-based components which is the best setup I found to make use of typescript checks for Vue components).
One more note: I was not able to reproduce the issue with vue test utils codebase - the same test passes with beta 30. There is a modified version that runs the same test twice that fails, but I am not sure if this is exactly same issue as described above, but maybe it will be useful too.
Project is generated with vue cli (default settings + unit-mocha, vue router and vue test utils):
npm install -g @vue/cli
vue create router-test
vue add unit-mocha
npm install --save @vue/[email protected]