programing

VueX에서 계산된 속성을 감시하는 Vue 워처를 테스트하려면 어떻게 해야 합니까?

newsource 2022. 9. 18. 12:49

VueX에서 계산된 속성을 감시하는 Vue 워처를 테스트하려면 어떻게 해야 합니까?

다음과 같은 컴포넌트가 있다고 가정합니다.

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

export default {
  name: 'Foo',
  computed: {
    ...mapState(['bar'])
  },
  watch: {
    bar () {
     externalDependency.doThing(this.bar);
    }
  }
}

테스트를 할 때 다음 사항을 확인하고 싶다.externalDependency.doThing()와 함께 호출됩니다.bar(vuex 상태로부터) 다음과 같이 됩니다.

it('should call externalDependency.doThing with bar', () => {
  const wrapper = mount(Foo);
  const spy = jest.spyOn(externalDependency, 'doThing');

  wrapper.setComputed({bar: 'baz'});

  expect(spy).toHaveBeenCalledWith('baz');
});

Vue test-utils에는 현재 테스트할 수 있는 setComputed 메서드가 있지만 setComputed가 곧 제거된다는 경고가 계속 표시되고 다른 테스트 방법을 알 수 없습니다.

https://github.com/vuejs/vue-test-utils/issues/331

당신이 달성하려고 하는 것부터

테스트 시 다음과 같이 externalDependency.doThing()이 바(vuex 상태에서 가져온)와 함께 호출되는지 확인합니다.

(이것은 순수한 유닛 테스트의 어프로치입니다), 기본적으로 함수인 이 워처를 강제로 변경할 수 있습니다.계산값이나 데이터값 변경 시 감시자가 변경되는지 추적할 필요가 없습니다. Vue가 처리하도록 하십시오.마운트된 Vue 인스턴스에서 워처를 변경하려면 다음과 같이 호출합니다.

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

어디에bar워처의 이름입니다.이렇게 하면 테스트하고자 하는 정확한 기능을 테스트할 수 있습니다.

vue-test-flash 문제에 대한 이 코멘트 https://github.com/vuejs/vue-test-utils/issues/331#issuecomment-382037200,에서 얻은 아이디어입니다.질문에서 언급하셨습니다.

Vue Test Utils 설명서에서는 다음과 같은 매우 단순한 Vuex 스토어를 사용하는 다른 방법을 설명합니다.

import { shallowMount, createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'

// use a localVue to prevent vuex state from polluting the global Vue instance
const 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');
  });
})

VueX 인스턴스에는 일종의 변이기가 필요합니다.그렇습니다.이것은 테스트와 관련이 없는 다른 유닛을 도입하는 것입니다만, 개인적으로 Vuex를 사용하는 것을 포함한 테스트에서는, 그 개념은 이미 깨져 있습니다.

예기치 않은 방법으로 상태를 변경하면 실제 사용량과 다른 동작이 발생하기 쉽습니다.

소스에서 값을 바로 설정할 수 있습니다.VueX. 그럼 매장에는 이런 것이 있습니다.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);

다음으로 component.spec.displays에서는 다음과 같이 합니다.

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');
});

전화도 할 수도 있습니다.dispatch('setBar', 'baz')직접 상태를 설정하지 않고 적절하게 변이가 발생하도록 합니다.

NB 모든 마운트에 대해 상태를 다시 초기화하는 것이 중요합니다(즉, 클론을 만들거나 다시 선언합니다).그렇지 않으면 한 테스트에 의해 상태가 변경될 수 있으며 래퍼 파괴가 발생한 경우에도 다음 테스트는 이 더러운 상태에서 시작됩니다.

언급URL : https://stackoverflow.com/questions/49431735/how-to-test-vue-watcher-that-watches-a-computed-property-from-vuex