В Vue-компонентах события ($emit) играют ключевую роль
для коммуникации между дочерними и родительскими компонентами. Vue Test
Utils предоставляет удобные инструменты для проверки того, какие события
были испущены, с какими аргументами и сколько раз. Это позволяет
создавать надёжные unit-тесты, контролирующие поведение компонентов.
wrapper.emitted() — центральный метод
для проверки событий. Он возвращает объект, где ключи — имена событий, а
значения — массив массивов с аргументами каждого вызова события.
import { mount } from '@vue/test-utils';
import MyButton from '@/components/MyButton.vue';
const wrapper = mount(MyButton);
wrapper.vm.$emit('click', 123);
console.log(wrapper.emitted());
// Вывод:
// {
// click: [[123]]
// }
Особенности:
Для проверки, было ли событие испущено хотя бы один раз, достаточно проверить наличие ключа:
expect(wrapper.emitted().click).toBeTruthy();
Для проверки количества вызовов:
expect(wrapper.emitted().click.length).toBe(2);
Проверка аргументов конкретного вызова:
expect(wrapper.emitted().click[0]).toEqual([123]);
expect(wrapper.emitted().click[1]).toEqual([456]);
Важно: Индексация начинается с нуля, первый вызов
события всегда в [0].
.emittedByOrder()Vue Test Utils позволяет проверять события в порядке их испускания
через метод emittedByOrder(). Это удобно, когда важен
последовательный вызов нескольких событий.
wrapper.vm.$emit('first', 'a');
wrapper.vm.$emit('second', 'b');
const emittedOrder = wrapper.emittedByOrder();
console.log(emittedOrder);
// [
// { name: 'first', args: ['a'] },
// { name: 'second', args: ['b'] }
// ]
Такой подход облегчает проверку сложной логики компонентов с цепочками событий.
События обычно испускаются в ответ на пользовательские действия. Vue Test Utils позволяет тестировать это через методы взаимодействия с компонентом.
const wrapper = mount(MyButton);
await wrapper.find('button').trigger('click');
expect(wrapper.emitted().click).toBeTruthy();
expect(wrapper.emitted().click[0]).toEqual([/* ожидаемые аргументы */]);
Особенности:
trigger асинхронный для событий, влияющих на
реактивное состояние.await можно безопасно проверять испущенные
события.Если событие испускается с объектом или массивом, важно использовать
глубокое сравнение через toEqual:
wrapper.vm.$emit('update', { id: 1, value: 'test' });
expect(wrapper.emitted().update[0]).toEqual([{ id: 1, value: 'test' }]);
Нельзя использовать toBe, так как он
проверяет строгое равенство ссылок, а не содержимое объектов.
Vue Test Utils прекрасно интегрируется с Jest, что позволяет писать выразительные проверки:
expect(wrapper.emitted().submit).toHaveLength(1);
expect(wrapper.emitted().submit[0]).toEqual([{ name: 'John' }]);
expect(wrapper.emitted().cancel).toBeUndefined();
toHaveLength проверяет количество вызовов события.toBeUndefined проверяет отсутствие события.Такой синтаксис делает тесты компактными и читаемыми.
Эта последовательность позволяет убедиться, что компонент не только испускает события, но и делает это корректно, в правильном порядке и с правильными данными.
При работе с TypeScript можно уточнять типы аргументов для события:
interface UpdateEvent {
id: number;
value: string;
}
const wrapper = mount<MyComponent>();
wrapper.vm.$emit('update', { id: 1, value: 'test' } as UpdateEvent);
const emitted = wrapper.emitted().update as UpdateEvent[][];
expect(emitted[0][0].id).toBe(1);
Такой подход повышает надёжность тестов и позволяет TypeScript проверять корректность данных.
v-model
событийВ Vue 3 v-model транслируется в событие
update:modelValue. Проверка его испускания не отличается от
обычных событий:
const wrapper = mount(MyInput);
await wrapper.find('input').setValue('Hello');
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['Hello']);
Методика идентична проверке стандартных событий, что упрощает тестирование двусторонней привязки данных.
Эти подходы формируют полноценный арсенал для проверки событий в компонентах Vue с помощью Vue Test Utils, обеспечивая точность, читаемость и надёжность unit-тестов.