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

后端 未结 4 1689
一个人的身影
一个人的身影 2021-02-12 12:53

Suppose I have the following component:

import { mapState } from \'vuex\';
import externalDependency from \'...\';

export default {
  name: \'Foo\',
  computed:         


        
4条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-12 13:07

    You can set the value straight at the source, i.e. VueX. so you'd have something like this in your store.js:

    const state = {
      bar: 'foo',
    };
    const mutations = {
      SET_BAR: (currentState, payload) => {
        currentState.bar = payload;
      },
    };
    const actions = {
      setBar: ({ commit }, payload) => {
        commit('SET_BAR', payload);
      },
    };
    
    export const mainStore = {
      state,
      mutations,
      actions,
    };
    
    export default new Vuex.Store(mainStore);
    

    and then in your component.spec.js you'd do this:

    import { mainStore } from '../store';
    import Vuex from 'vuex';
    
    //... describe, and other setup functions
    it('should call externalDependency.doThing with bar', async () => {
      const localState = {
        bar: 'foo',
      };
      const localStore = new Vuex.Store({
          ...mainStore,
          state: localState,
      });
      const wrapper = mount(Foo, {
        store: localStore,
      });
      const spy = jest.spyOn(externalDependency, 'doThing');
      localStore.state.bar = 'baz';
      await wrapper.vm.$nextTick();
      expect(spy).toHaveBeenCalledWith('baz');
    });
    

    You can also call the dispatch('setBar', 'baz') method on the store and have the mutation occur properly instead of directly setting the state.

    NB It's important to re-initialize your state for every mount (i.e. either make a clone or re-declare it). Otherwise one tests can change the state and the next test will start with that dirty state, even if wrapper was destroyed.

提交回复
热议问题