我正在为使用Vuex作为商店的vuejs 2应用程序编写单元测试。我的许多组件都有以下模式:
示例组件thing.vue:
<template>
<div>
{{ thing.label }}
</div>
</template>
<script>
export default {
name: 'thing',
data() { return { } },
computed: {
thing () {
return this.$store.state.thing;
}
}
}
</script>
示例商店状态:
export const state = {
thing: { label: 'test' }
};
Thing.vue的示例单位:
describe('thing ', () => {
const storeMock = new Vuex.Store( state: { thing: { label: 'test' } } );
it('should pull thing from store', () => {
const Constructor = Vue.extend(thing);
const component new Constructor({ store }).$mount();
expect(component.thing).toEqual({ label: 'test' });
});
});
商店的单元测试示例:
import store from './store';
describe('Vuex store ', () => {
it('should have a thing object', () => {
expect(store.state.thing).toEqual({ label: 'test' });
});
});
这种模式存在很大问题。当另一个开发人员折射存储状态时,他们会看到存储测试失败,但是因为事物单元测试基于测试的模拟版本继续传递,即使该组件永远不会工作。知道重构无效的模拟方法并不是一个好方法。
那么人们如何对这种依赖进行单元测试?
一种方法是在单元测试中作弊并使用实际存储状态,但它不是真正的单元测试。另一种方法是依靠集成测试来捕捉模拟 - 存储不匹配,但感觉调试为什么单元测试通过但集成测试失败会很痛苦。
答案 0 :(得分:0)
我们最终做的是使用实际商店。因为商店状态只是一个对象,我们认为它是可以接受的。
我们还使用商店的吸气剂,动作和突变作为茉莉花谍的模板。
// Vuex needs polyfill
import { polyfill } from 'es6-promise';
polyfill();
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import test from 'app/components/test.vue';
import module from 'app/store/modules/module';
describe('Spec for Test.vue', () => {
var props;
var state;
var actions;
var mutations;
var getters;
var store;
beforeEach( () => {
jasmine.addMatchers(customMatchers);
props = { };
// Don't change the modules
state = Object.assign({}, module.state);
actions = Object.assign({}, module.actions);
mutations = Object.assign({}, module.mutations);
getters = Object.assign({}, module.getters);
// Add require global actions, mutations, and getters here...
actions.globalActionHere = 'anything'; // this turns into a spy
// Update State with required fields
state.defaults = { id: 1 } // default expected when the component loads
// Replace modules copies with mocks
actions = jasmine.createSpyObj('actions', actions);
mutations = jasmine.createSpyObj('mutations', mutations);
getters = jasmine.createSpyObj('getters', getters);
store = new Vuex.Store( { state: { module: state }, getters, actions, mutations } );
} );
it('should have a name of test', () => {
const Constructor = Vue.extend(thing);
const component new Constructor({ store, props }).$mount();
expect(component.$options.name).toBe('test');
});
});
注意部分
jasmine.createSpyObj('actions', actions);
Jasmine spies将使用该模块为每个方法创建spyies,这非常有用。