В экосистеме Vue.js computed свойства играют ключевую
роль в реактивном отображении состояния, часто зависящего от Vuex store.
Правильное тестирование этих вычисляемых свойств позволяет убедиться,
что компоненты корректно реагируют на изменения состояния
приложения.
Для работы с Vue Test Utils потребуется:
Пример установки зависимостей через npm:
npm install @vue/test-utils vuex jest --save-dev
Для тестирования computed свойств, зависящих от store,
необходимо передавать mock store или реальный экземпляр Vuex. Это
достигается через параметр global.plugins при монтировании
компонента:
import { mount } from '@vue/test-utils';
import Vuex from 'vuex';
import MyComponent from '@/components/MyComponent.vue';
const state = {
count: 5
};
const getters = {
doubleCount: (state) => state.count * 2
};
const store = new Vuex.Store({
state,
getters
});
const wrapper = mount(MyComponent, {
global: {
plugins: [store]
}
});
Здесь ключевым моментом является использование getters
для вычисляемых значений. Компонент может иметь computed
свойство, которое напрямую использует mapGetters или
обращается к store через this.$store.getters.
computed свойстваПосле монтирования компонента проверка computed свойства
выполняется через обращение к экземпляру компонента
wrapper.vm:
test('computed doubleCount возвращает правильное значение', () => {
expect(wrapper.vm.doubleCount).toBe(10);
});
Особенности:
wrapper.vm содержит экземпляр Vue-компонента.computed свойства, зависящие от state или
getters, доступны напрямую.Одним из основных преимуществ Vuex является реактивность. Чтобы
проверить, что computed свойство корректно обновляется при
изменении состояния:
test('computed обновляется при изменении state', async () => {
store.state.count = 10;
await wrapper.vm.$nextTick();
expect(wrapper.vm.doubleCount).toBe(20);
});
Ключевые моменты:
state напрямую через store имитирует действия
приложения.await wrapper.vm.$nextTick() гарантирует,
что Vue успел пересчитать computed.Для unit-тестов предпочтительно использовать mock store вместо
реального Vuex. Это позволяет полностью контролировать состояние и
поведение getters:
const mockGetters = {
doubleCount: () => 42
};
const wrapper = mount(MyComponent, {
global: {
mocks: {
$store: {
getters: mockGetters
}
}
}
});
test('computed возвращает значение из mock getters', () => {
expect(wrapper.vm.doubleCount).toBe(42);
});
Преимущества mock store:
getters.computed с mapState и mapGettersVue предоставляет вспомогательные функции для подключения к store:
mapState и mapGetters. При их использовании
тестирование не изменяется, но важно учитывать правильное определение
store при монтировании компонента:
computed: {
...mapGetters(['doubleCount'])
}
В тесте:
expect(wrapper.vm.doubleCount).toBe(store.getters.doubleCount);
Если используется mapState:
computed: {
...mapState(['count'])
}
Тогда проверка computed свойства напрямую связана с
state:
expect(wrapper.vm.count).toBe(store.state.count);
Иногда computed свойства зависят от результатов
асинхронных операций через store. В этом случае рекомендуется
использовать мокнутые actions и имитацию обновления state:
const actions = {
fetchCount: jest.fn(() => {
store.state.count = 15;
})
};
await actions.fetchCount();
await wrapper.vm.$nextTick();
expect(wrapper.vm.doubleCount).toBe(30);
Такой подход позволяет тестировать логику computed, не
выполняя реальных HTTP-запросов.
computedcomputed.await wrapper.vm.$nextTick() для
обновления реактивных данных.Этот подход позволяет покрывать unit-тестами все вычисляемые свойства компонента, полностью контролируя зависимость от Vuex store.