unit-testingvue.jsvuexavoriazvue-test-utils

How to unit test VueJS watcher on $route


I'm testing a Single file component that uses vue router to watch $route. The problem is that I can't get the test to both change the route and trigger the watcher's function.

The test file:

import { createLocalVue, shallow } from 'vue-test-utils';

import Vue from 'vue';
import Vuex from 'vuex';
const localVue = createLocalVue();
localVue.use(Vuex);

const $route = {
  path: '/my/path',
  query: { uuid: 'abc' },
}

wrapper = shallow({
  localVue,
  store,
  mocks: {
   $route,
  }
});

it('should call action when route changes', () => {
    // ensure jest has a clean state for this mocked func
    expect(actions['myVuexAction']).not.toHaveBeenCalled();
    vm.$set($route.query, 'uuid', 'def');
    //vm.$router.replace(/my/path?uuid=def') // tried when installing actual router
    //vm.$route.query.uuid = 'def'; // tried
    //vm.$route = { query: { uuid: 'def'} }; // tried
    expect(actions['myVuexAction']).toHaveBeenLastCalledWith({ key: true });
});

My watch method in the SFC:

  watch: {
    $route() {
      this.myVuexAction({ key: true });
    },
  },

How do you mock router in such a way that you can watch it and test the watch method is working as you expect?


Solution

  • The way to do this actually is to use vue-test-utils wrapper method, setData.

    wrapper.setData({ $route: { query: { uuid: 'def'} } });