Skip to content

Refactoring options api to use vue-router/composables break basic unit tests #3802

@renatodeleao

Description

@renatodeleao

Version

3.6.5

Reproduction link

stackblitz.com

Steps to reproduce

  1. Giving a basic options API component
    <!-- using options API -->
    <template>
       <div>{{ msg }}</div>
    </template>
    
    <script>
    export default {
      computed: {
          msg() {
             return `My route name is ${this.$route.name}`;
          }
      }
    };
    </script>
  2. refactoring to composition api
    <!-- Refactoring using composition-api -->
    <script>
    import { useRoute } from 'vue-router/composables';
    import { computed } from 'vue';
    
    export default {
      setup() {
        const $route = useRoute();
        const msg = computed(() => {
          `My route name is ${$route.name}`;
        });
    
        return {
          msg,
        };
      },
    };
    </script>
  3. The test that worked before, now breaks.
    import { mount } from '@vue/test-utils';
    import SomeComponent from './SomeComponent.vue';
    
    const $route = {
      path: '/some/path',
    };
    
    function Wrapper() {
      return mount(SomeComponent, {
        mocks: {
          $route,
        },
      });
    }
    
    test('mount component',  () => {
      const wrapper = Wrapper();
      
      expect(wrapper.exists()).toBe(true);
      // TypeError: Cannot read properties of undefined (reading 'currentRoute')
    });

What is expected?

using options/composition-api should not affect the test suite output

What is actually happening?

Using options/composition-api requires different ways to test (mock)


Additional Comments

Link to reproduction with same component written in "options API" mode
https://stackblitz.com/edit/vitejs-vite-rdjvxj?file=src%2Fviews%2FAbout.test.js

Heya! 👋
While I was waiting for the 3.6.x release, I rolled some in-house vue-router hooks as per #3760 (comment). This allowed refactoring some options-API components to composition-api "mode" while keeping my test suite intact.

I thought the refactor to use the official package hooks would be a simple find/replace but my test suite broke. After some digging, the reason is that the hooks implementation relies on router.currentRoute property and afterEach hook, which made the tests using the simplest $route mock as suggested in vue-test-utils docs to fail.

Of course there's several ways to fix it: updating the test mocks as below; setting up a router with localVue as per docs; stubbing modules jest.mock(); etc;

import { mount } from '@vue/test-utils';
import SomeComponent from './SomeComponent.vue';

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

function Wrapper() {
  return mount(SomeComponent, {
    mocks: {
-      $route,
+      $router: { currentRoute: $route, afterEach: vitest.fn() },
    },
  });
}

Question

If you went this way1, I'm sure there are good reasons for it. I'm just curious on why didn't you go with a similar approach as vue-router@4, as in, with a reactive object derived from getCurrentInstance().proxy.$route as per2 which kept tests working without any change — but surely break some other stuff.


Cheers and thanks for your work on the router! Feel free to close this if you think it's related with @vue/test-utils docs instead ✌️

Footnotes

  1. https://github.com/vuejs/vue-router/blob/e3273b3db905f0d162d57725fba0c459ea5bb463/src/composables/globals.js#L23-L30

  2. https://github.com/vuejs/vue-router/pull/3763/commits/f1eb2b1dba9b5cc5011b230a3121c882d883c4c0#diff-2042e0452c0d0edd730403740acc8d4337382101087ad62a677e1e2fdae05e8fR8-R17

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy