Я создаю новый компонент Vue, который использует геттер Vuex с пространством имен для доступа к списку имен столбцов. Фактический компонент компилируется и запускается.
В своих модульных тестах Mocha я создал фиктивный геттер, который возвращает список строк с именем «allColumns». Когда я запускаю модульные тесты во время ShallowMount, методы компонента пытаются получить доступ к this.allColumns во время инициализации, но значение всегда не определено. Я вижу нужное мне значение в this.$store.getters.allColumns, но оно не сопоставляется с this.allColumns, как это происходит, когда я открываю страницу в браузере.
Существует много информации о том, как имитировать геттеры в тесте и как использовать mapGetters с пространством имен, но я не нашел никакой документации о геттерах с пространством имен в тесте Mocha.
test.spec.js
let propsData;
let getters;
let store;
beforeEach(() => {
debugger;
propsData = {
players: samplePlayerObject,
metadata: sampleMetadataObject
};
getters = {
allColumns: () => ["playerid","last","first","birthday","height"]
}
store = new Vuex.Store({
getters
});
})
it('initializes the component', () => {
const wrapper = shallowMount(PlayerFilterTable, { propsData, localVue, store });
});
vue-компонент
<template>
<div class = "player-filter-table">
<table>
<tr>
<th v-for = "(key, index) in GetColumns()"
v-bind:id = "'header-' + key"
v-bind:key = "index"
@click = "HeaderClick(key)"
>...</th>
</tr>
</table>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
computed: {
...mapGetters({
allColumns: 'playerFilter/allColumns'
})
},
GetColumns() {
// this.allColumns is defined when running in browser, but undefined when loaded from a Mocha test
return this.allColumns.filter(column => [*some filter criteria*]);
}
</script>
Когда smallMount запускается в test.spec.js, я ожидаю, что компонент успешно загрузится, а затем продолжит выполнение моих тестов, но вместо этого я получаю сообщение об ошибке TypeError: Cannot read property 'filter' of undefined, потому что this.allColumns не определенный.
Используйте modules
с namespaced: true
:
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import PlayerFilterTable from '~/whatever';
const localVue = createLocalVue();
localVue.use(Vuex);
let propsData, getters, store, wrapper, consoleSpy;
describe('PlayerFilterTable', () => {
beforeEach(() => {
consoleSpy = jest.spyOn(console, 'error');
propsData = {
players: samplePlayerObject,
metadata: sampleMetadataObject
};
getters = {
allColumns: () => ["playerid", "last", "first", "birthday", "height"]
};
store = new Vuex.Store({
modules: {
playerFilter: {
namespaced: true,
getters
}
}
});
wrapper = shallowMount(PlayerFilterTable, {
propsData,
localVue,
store
});
});
afterEach(() => {
expect(consoleSpy).not.toHaveBeenCalled();
});
it('should render correctly', () => {
expect(wrapper.is(PlayerFilterTable)).toBe(true);
expect(wrapper.html()).toMatchSnapshot();
})
})
Если вы используете геттеры из более чем одного модуля, вы можете сгруппировать их под разными реквизитами getters
и соответствующим образом назначить каждому модулю.
Это правильное решение. Большое спасибо! Я бился с этим пару дней.