Skip to content

serebrov/vue-test-utils-router-push-issue

Repository files navigation

Summary

  • 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)
  • 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.

Details

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 setup

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]

About

A demo of the issue with router.push and vue-test-utils

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published