假设我有以下组件:
import { mapState } from 'vuex';
import externalDependency from '...';
export default {
name: 'Foo',
computed: {
...mapState(['bar'])
},
watch: {
bar () {
externalDependency.doThing(this.bar);
}
}
}
测试时,我想确保使用externalDependency.doThing()
(来自vuex状态)调用bar
,如下所示:
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将很快被删除,我不知道如何测试它:
答案 0 :(得分:1)
您可以直接在源(即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 :(得分:1)
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');
});
})
答案 2 :(得分:1)
您正在尝试实现的目标
在测试时,我想确保使用bar(来自vuex状态)调用externalDependency.doThing(),如下所示:
(这确实是纯单元测试方法),您可以强制更改此观察程序,这基本上是一个功能。 无需跟踪观察者是否在计算值或数据值更改的情况下进行更改-让Vue处理。 因此,要在已安装的Vue实例中更改观察者,只需将其命名为
wrapper.vm.$options.watch.bar.call(wrapper.vm)
bar
是监视者的姓名。这样,您将能够测试要测试的确切功能。
此评论https://github.com/vuejs/vue-test-utils/issues/331#issuecomment-382037200中有关您在问题中提到的vue-test-utils问题的想法。
答案 3 :(得分:0)
您将在VueX实例上需要某种变体,是的,这确实为测试引入了另一个不相关的单元,但是就您个人而言,包括使用Vuex在内,您的测试已经被打破。
以意外方式修改状态更容易导致行为与实际用法不同。