В тестировании Vue-компонентов ключевое место занимает проверка actions — функций, вызываемых при взаимодействии с компонентом, таких как клик по кнопке, изменение данных формы или вызов методов Vuex. Правильное тестирование действий позволяет убедиться, что компонент корректно реагирует на события и взаимодействует с состоянием приложения.
Для начала необходимо настроить тестовое окружение с использованием Vue Test Utils и тестового раннера, например, Jest. Основные импорты:
import { mount } from '@vue/test-utils';
import Component from '@/components/Component.vue';
Для компонентов, использующих Vuex, необходимо подключение мок-стора:
import Vuex from 'vuex';
const actions = {
myAction: jest.fn()
};
const store = new Vuex.Store({
actions
});
Здесь jest.fn() создаёт имитацию функции, которая
позволяет отслеживать вызовы действия.
1. Проверка вызова метода компонента при событии
Методы компонентов можно проверять через wrapper.vm или
через вызов события. Например, метод submitForm должен
вызываться при сабмите формы:
const wrapper = mount(Component);
const form = wrapper.find('form');
form.trigger('submit.prevent');
expect(wrapper.vm.submitForm).toHaveBeenCalled();
Ключевой момент: .trigger('event') симулирует событие, а
.toHaveBeenCalled() проверяет, что метод был вызван.
2. Проверка Vuex actions
Если компонент диспатчит action Vuex, используется мок-store.
Например, компонент вызывает myAction при клике на
кнопку:
const wrapper = mount(Component, { global: { plugins: [store] } });
const button = wrapper.find('button');
button.trigger('click');
expect(actions.myAction).toHaveBeenCalled();
Можно также проверить, что action был вызван с правильными аргументами:
expect(actions.myAction).toHaveBeenCalledWith(expect.anything(), { id: 123 });
expect.anything() используется для аргумента
context, который Vuex передает автоматически.
Многие actions являются асинхронными. Для их тестирования важно
использовать async/await и методы
flushPromises:
import flushPromises from 'flush-promises';
actions.asyncAction = jest.fn(() => Promise.resolve('done'));
const wrapper = mount(Component, { global: { plugins: [store] } });
wrapper.find('button').trigger('click');
await flushPromises();
expect(actions.asyncAction).toHaveBeenCalled();
flushPromises гарантирует выполнение всех промисов перед
проверкой вызовов, что исключает ложные отрицательные результаты
теста.
Важно контролировать частоту вызова action и передаваемые данные:
expect(actions.myAction).toHaveBeenCalledTimes(1);
expect(actions.myAction).toHaveBeenCalledWith(expect.anything(), { name: 'John' });
toHaveBeenCalledTimes(n) — проверяет количество
вызовов.toHaveBeenCalledWith(...) — проверяет точные
аргументы.Эти проверки особенно важны для сложных форм и компонентов с динамическими действиями.
Иногда нужно проверить внутренние методы компонента, не только Vuex
actions. В этом случае используется jest.spyOn:
const spy = jest.spyOn(Component.methods, 'localMethod');
const wrapper = mount(Component);
wrapper.find('button').trigger('click');
expect(spy).toHaveBeenCalled();
spy.mockRestore();
mockRestore восстанавливает исходную функцию, что
предотвращает побочные эффекты в других тестах.
Для проверки множества действий с разными аргументами удобно
использовать test.each:
test.each([
['John', 1],
['Jane', 2]
])('диспатч action с %s и %i', async (name, id) => {
const wrapper = mount(Component, { global: { plugins: [store] } });
wrapper.find('button').trigger('click');
await flushPromises();
expect(actions.myAction).toHaveBeenCalledWith(expect.anything(), { name, id });
});
Это позволяет легко покрывать комплексные сценарии без дублирования кода.
Если компонент вызывает несколько действий в определённой последовательности, важно проверять порядок вызовов:
const firstAction = jest.fn();
const secondAction = jest.fn();
const store = new Vuex.Store({ actions: { firstAction, secondAction } });
const wrapper = mount(Component, { global: { plugins: [store] } });
wrapper.find('button').trigger('click');
expect(firstAction).toHaveBeenCalledBefore(secondAction);
Для этого можно использовать сторонние Jest-плагины, такие как
jest-extended, которые расширяют стандартные
матчер-функции.
Тестирование действий во Vue Test Utils — это проверка корректной реакции компонентов на события и правильного взаимодействия с Vuex. Основные принципы включают:
.trigger().async/await и
flushPromises.Эти подходы позволяют создавать надёжные, поддерживаемые тесты, которые точно отражают поведение компонентов и их действий.