Мутации в Vuex — это синхронные функции, изменяющие состояние хранилища. Тестирование мутаций позволяет убедиться, что при вызове конкретной функции состояние изменяется предсказуемо. В отличие от действий (actions), которые могут быть асинхронными и вызывать API, мутации выполняются мгновенно, что делает их идеальными для прямого юнит-тестирования.
Мутация в Vuex определяется как функция с двумя параметрами:
state и payload.
const mutations = {
increment(state, payload) {
state.count += payload.amount;
},
setUser(state, user) {
state.user = user;
}
};
Главный принцип тестирования мутации — проверить, что при
определенном state и payload состояние
изменяется ожидаемым образом.
Для тестирования мутации используют простой подход: создается локальный объект состояния, вызывается мутация, затем проверяется результат.
import { mutations } from '@/store/mutations';
describe('mutations', () => {
it('increment увеличивает count на заданное значение', () => {
const state = { count: 0 };
const payload = { amount: 5 };
mutations.increment(state, payload);
expect(state.count).toBe(5);
});
it('setUser обновляет объект пользователя', () => {
const state = { user: null };
const user = { id: 1, name: 'Alice' };
mutations.setUser(state, user);
expect(state.user).toEqual(user);
});
});
Ключевые моменты:
state, чтобы тесты были
детерминированными.toBe для примитивов и
toEqual для объектов.Если мутация содержит более сложные операции, например обновление вложенных объектов или массивов, важно проверить все возможные ветвления.
const mutations = {
addTodo(state, todo) {
state.todos.push(todo);
},
toggleTodo(state, id) {
const todo = state.todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
}
}
};
describe('todo mutations', () => {
let state;
beforeEach(() => {
state = { todos: [{ id: 1, text: 'Learn Vue', completed: false }] };
});
it('addTodo добавляет новый элемент', () => {
const newTodo = { id: 2, text: 'Write tests', completed: false };
mutations.addTodo(state, newTodo);
expect(state.todos.length).toBe(2);
expect(state.todos[1]).toEqual(newTodo);
});
it('toggleTodo меняет completed на противоположное значение', () => {
mutations.toggleTodo(state, 1);
expect(state.todos[0].completed).toBe(true);
mutations.toggleTodo(state, 1);
expect(state.todos[0].completed).toBe(false);
});
});
Особенности:
beforeEach гарантирует чистое состояние
для каждого теста.Мутации должны быть синхронными и не вызывать асинхронные операции или прямой доступ к API. Если мутация изменяет несколько полей состояния одновременно, важно тестировать все изменения:
const mutations = {
updateProfile(state, profile) {
state.user.name = profile.name;
state.user.email = profile.email;
}
};
describe('updateProfile', () => {
it('обновляет имя и email пользователя', () => {
const state = { user: { name: 'Bob', email: 'bob@example.com' } };
const profile = { name: 'Alice', email: 'alice@example.com' };
mutations.updateProfile(state, profile);
expect(state.user.name).toBe('Alice');
expect(state.user.email).toBe('alice@example.com');
});
});
state для каждого
теста.toEqual).Хотя Vue Test Utils ориентирован на тестирование компонентов, мутации часто проверяются отдельно. В интеграционных тестах компонентов можно проверять, что событие компонента вызывает нужную мутацию через моки хранилища:
import { shallowMount } from '@vue/test-utils';
import Counter from '@/components/Counter.vue';
const mutations = {
increment: jest.fn()
};
const store = {
state: { count: 0 },
mutations
};
describe('Counter.vue', () => {
it('вызывает increment при клике', async () => {
const wrapper = shallowMount(Counter, {
global: { mocks: { $store: store } }
});
await wrapper.find('button').trigger('click');
expect(mutations.increment).toHaveBeenCalled();
});
});
Особенности интеграции:
jest.fn) для отслеживания вызова
мутации.Проверка мутаций является фундаментальной частью тестирования Vuex. Изоляция, детерминированность и тщательная проверка всех изменений состояния обеспечивают надежность и предсказуемость приложения при масштабировании.