次のコンポーネントがあるとします。
_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がまもなく削除されるという警告が表示され続け、他にどのようにテストできるかわかりません。
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で値を直接設定できます。だからあなたはあなたの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);
_
そしてあなたのcomponent.spec.jsであなたはこれをするでしょう:
_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 [〜#〜]マウントごとに状態を再初期化することが重要です(つまり、クローンを作成するか、再宣言します)。そうしないと、ラッパーが破棄された場合でも、1つのテストで状態が変更され、次のテストはそのダーティ状態で開始されます。
VueXインスタンスにはある種のミューテーターが必要になります。そうです、これはテストに別の無関係なユニットを導入しますが、個人的にはVuexの使用を含むテストによって、その概念はすでに破られています。
予期しない方法で状態を変更すると、実際の使用法とは異なる動作が発生する可能性が高くなります。