Проверка данных события

Vue Test Utils предоставляет мощный инструментарий для тестирования компонентов Vue, включая возможность детальной проверки событий, которые компоненты эмитируют. Важным аспектом является проверка payload’а события — данных, передаваемых при эмиссии. Это критично для компонентов, которые взаимодействуют через кастомные события.

Эмитирование событий

Компоненты Vue могут генерировать события с помощью метода $emit. Пример простого компонента:

<template>
  <button @click="sendData">Отправить</button>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit('submit', { name: 'John', age: 30 });
    }
  }
}
</script>

Здесь при клике по кнопке будет сгенерировано событие submit с объектом в качестве данных.

Монтирование компонента для теста

Для проверки событий компонент нужно смонтировать с помощью функции mount из Vue Test Utils:

import { mount } from '@vue/test-utils';
import MyButton from '@/components/MyButton.vue';

const wrapper = mount(MyButton);

После монтирования можно управлять DOM и отслеживать события.

Проверка эмитированных событий

Vue Test Utils предоставляет метод emitted() для получения списка всех эмитированных событий. Возвращаемое значение — объект, где ключи — названия событий, а значения — массивы массивов с аргументами:

wrapper.find('button').trigger('click');

expect(wrapper.emitted().submit).toBeTruthy(); // проверка, что событие с эмитировано
expect(wrapper.emitted().submit.length).toBe(1); // событие было вызвано один раз

Проверка данных события

Чтобы проверить данные, переданные вместе с событием, используется индексация по событию и его вызовам:

const eventPayload = wrapper.emitted().submit[0][0]; 
expect(eventPayload).toEqual({ name: 'John', age: 30 });
  • wrapper.emitted().submit — массив всех вызовов события submit.
  • [0] — первый вызов.
  • [0] — первый аргумент, переданный в событие.

Множественные аргументы события

События могут передавать несколько параметров:

this.$emit('update', 'active', { id: 1 });

Для проверки данных используется аналогичный подход:

wrapper.vm.$emit('update', 'active', { id: 1 });
const args = wrapper.emitted().update[0];
expect(args[0]).toBe('active');
expect(args[1]).toEqual({ id: 1 });

Проверка количества эмиссий

Для компонентов, которые могут эмитировать событие несколько раз, важно проверять количество вызовов:

wrapper.vm.$emit('increment');
wrapper.vm.$emit('increment');

expect(wrapper.emitted().increment.length).toBe(2);

Отслеживание событий через trigger

trigger позволяет эмулировать пользовательские действия и автоматически отслеживать эмитированные события:

wrapper.find('button').trigger('click');

expect(wrapper.emitted('submit')[0][0]).toEqual({ name: 'John', age: 30 });
  • Первый аргумент trigger — название события DOM.
  • Эмитируемое событие компонента проверяется через emitted().

Проверка событий с асинхронными действиями

Если эмитирование события зависит от асинхронной логики, используется nextTick:

await wrapper.find('button').trigger('click');
await wrapper.vm.$nextTick();

expect(wrapper.emitted().submit[0][0]).toEqual({ name: 'John', age: 30 });

Это гарантирует, что события полностью обработаны перед проверкой.

Использование props для проверки событий

Компоненты могут эмитировать события при изменении пропсов:

const wrapper = mount(MyButton, {
  props: { value: 'test' }
});
wrapper.setProps({ value: 'new' });

expect(wrapper.emitted('update:value')[0][0]).toBe('new');

emitted() фиксирует события, которые вызваны реактивными изменениями пропсов.

Рекомендации по тестированию событий

  • Проверять название события точно, включая регистр.
  • Проверять payload с помощью toEqual для глубокого сравнения объектов.
  • При множественных аргументах — проверять каждый по индексу.
  • Для асинхронных эмиссий использовать await nextTick().
  • Следить за количеством вызовов события, чтобы избежать ложноположительных результатов.

Эта методология позволяет создавать надёжные тесты взаимодействия компонентов, гарантируя, что события эмитируются корректно и данные передаются точно так, как ожидается.