How to test Vue watcher that watches a computed property from VueX? How to test Vue watcher that watches a computed property from VueX? vue.js vue.js

How to test Vue watcher that watches a computed property from VueX?


From you're trying to achieve

When testing, I want to ensure that externalDependency.doThing() is called with bar (which comes from the vuex state) like so:

(and this is indeed pure unit test approach), you can just force change of this watcher, which basically is a function.There's no need to track if watcher is changing in case of computed or data value change - let Vue handle it.So, to change a watcher in a mounted Vue instance, just call it like

wrapper.vm.$options.watch.bar.call(wrapper.vm)

Where bar is name of your watcher. This way you will be able to test exact functionality that you're aiming to test.

Idea taken from this comment https://github.com/vuejs/vue-test-utils/issues/331#issuecomment-382037200, on a vue-test-utils issue, mentioned by you in a question.


The Vue Test Utils documentation points at a different approach where you use a very simple Vuex store:

import { shallowMount, createLocalVue } from '@vue/test-utils'import Vuex from 'vuex'// use a localVue to prevent vuex state from polluting the global Vue instanceconst localVue = createLocalVue();localVue.use(Vuex);describe('Foo.vue', () => {  let state;  let store;  beforeEach(() => {    // create a new store for each test to prevent pollution    state = { bar: 'bar' };    store = new Vuex.Store({ state });  })  it('should call externalDependency.doThing with bar', () =>   {    shallowMount(MyComponent, { store, localVue });    const spy = jest.spyOn(externalDependency, 'doThing');    // trigger the watch    state.bar = 'baz';    expect(spy).toHaveBeenCalledWith('baz');  });})


You will need some sort of mutator on the VueX instance, yes this does introduce another unrelated unit to the test but personally by your test including the use of Vuex, that concept has already been broken.

Modifying the state in an unexpected way is more prone to cause behaviour that differs from the actual usage.