在组件单元测试中模拟 Vuex 模块动作
Mocking Vuex module action in component unit test
我目前正在尝试模拟商店模块中的操作。我似乎无法正确存根,因为我在单元测试中继续收到一条消息:
[vuex] unknown action type: moduleA/filterData
这是被测组件的简化版本:
Item.vue
<template>
<li class="list-item"
@click="toggleActive()">
{{ itemName }}
</li>
</template>
<script>
import store from '../store'
export default {
name: 'item',
props: {
itemName: {
type: String
}
},
data () {
return {
store,
isActive: false
}
},
methods: {
toggleActive () {
this.isActive = !this.isActive;
this.$store.dispatch('moduleA/filterData', { name: itemName } );
}
}
}
</script>
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
moduleA
}
});
export default store;
moduleA.js
/* imports */
const state = {
/* state */
}
const mutations = {
/* ... */
}
const actions = {
filterData({ state, commit }, payload) {
/* filter data and commit mutations */
}
}
const getters = {
/* getters */
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
Item.spec.js
import Vue from 'vue'
import { mount } from '@vue/test-utils'
import { expect } from 'chai'
import sinon from 'sinon'
import Item from '../src/components/Item.vue'
import Vuex from 'vuex'
Vue.use(Vuex);
describe('Item.vue', () => {
let componentProps = {};
let wrapper;
let actions;
let store;
beforeEach(() => {
let name = 'Item Name';
// mock vuex action on click
actions = {
filterData: sinon.stub()
}
let moduleA = {
state: {},
actions
}
store = new Vuex.Store({
modules: {
moduleA
}
});
componentProps.itemName = name;
wrapper = mount(Item, {
store: store,
propsData: componentProps
});
})
it('Has a root element of list-item', () => {
expect(wrapper.is('.list-item')).to.equal(true);
})
it('Item getting prop name', () => {
expect(wrapper.text()).to.equal('Item Name');
})
it('Item is not active on load', () => {
expect(wrapper.vm.$data.isActive).to.equal(false);
})
it('Item is active after click', () => {
wrapper.trigger('click');
expect(wrapper.vm.$data.isActive).to.equal(true);
})
it('Item is not active after two clicks', () => {
wrapper.trigger('click');
wrapper.trigger('click');
expect(wrapper.vm.$data.isActive).to.equal(false);
})
})
这不会导致我的测试失败,但我一直无法找到如何从 Vuex 中正确地 mock/stub 模块操作。感谢任何帮助。
所以我调查了这个,结果发现我没有在我的测试中定义我的商店是命名空间的,因此它没有识别我的操作:
beforeEach(() => {
let name = 'Item Name';
// mock vuex action on click
actions = {
filterData: sinon.stub()
}
let moduleA = {
namespaced: true,
state: {},
actions
}
store = new Vuex.Store({
modules: {
moduleA
}
});
componentProps.itemName = name;
wrapper = mount(Item, {
store: store,
propsData: componentProps
});
})
包含这个之后我的错误就消失了。
我目前正在尝试模拟商店模块中的操作。我似乎无法正确存根,因为我在单元测试中继续收到一条消息:
[vuex] unknown action type: moduleA/filterData
这是被测组件的简化版本:
Item.vue
<template>
<li class="list-item"
@click="toggleActive()">
{{ itemName }}
</li>
</template>
<script>
import store from '../store'
export default {
name: 'item',
props: {
itemName: {
type: String
}
},
data () {
return {
store,
isActive: false
}
},
methods: {
toggleActive () {
this.isActive = !this.isActive;
this.$store.dispatch('moduleA/filterData', { name: itemName } );
}
}
}
</script>
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
moduleA
}
});
export default store;
moduleA.js
/* imports */
const state = {
/* state */
}
const mutations = {
/* ... */
}
const actions = {
filterData({ state, commit }, payload) {
/* filter data and commit mutations */
}
}
const getters = {
/* getters */
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
Item.spec.js
import Vue from 'vue'
import { mount } from '@vue/test-utils'
import { expect } from 'chai'
import sinon from 'sinon'
import Item from '../src/components/Item.vue'
import Vuex from 'vuex'
Vue.use(Vuex);
describe('Item.vue', () => {
let componentProps = {};
let wrapper;
let actions;
let store;
beforeEach(() => {
let name = 'Item Name';
// mock vuex action on click
actions = {
filterData: sinon.stub()
}
let moduleA = {
state: {},
actions
}
store = new Vuex.Store({
modules: {
moduleA
}
});
componentProps.itemName = name;
wrapper = mount(Item, {
store: store,
propsData: componentProps
});
})
it('Has a root element of list-item', () => {
expect(wrapper.is('.list-item')).to.equal(true);
})
it('Item getting prop name', () => {
expect(wrapper.text()).to.equal('Item Name');
})
it('Item is not active on load', () => {
expect(wrapper.vm.$data.isActive).to.equal(false);
})
it('Item is active after click', () => {
wrapper.trigger('click');
expect(wrapper.vm.$data.isActive).to.equal(true);
})
it('Item is not active after two clicks', () => {
wrapper.trigger('click');
wrapper.trigger('click');
expect(wrapper.vm.$data.isActive).to.equal(false);
})
})
这不会导致我的测试失败,但我一直无法找到如何从 Vuex 中正确地 mock/stub 模块操作。感谢任何帮助。
所以我调查了这个,结果发现我没有在我的测试中定义我的商店是命名空间的,因此它没有识别我的操作:
beforeEach(() => {
let name = 'Item Name';
// mock vuex action on click
actions = {
filterData: sinon.stub()
}
let moduleA = {
namespaced: true,
state: {},
actions
}
store = new Vuex.Store({
modules: {
moduleA
}
});
componentProps.itemName = name;
wrapper = mount(Item, {
store: store,
propsData: componentProps
});
})
包含这个之后我的错误就消失了。