Контроль вызовов функций

В тестировании компонентов Vue особое внимание уделяется поведению методов и их взаимодействию с событиями. Контроль вызовов функций позволяет убедиться, что методы компонента вызываются корректно, с правильными аргументами и ожидаемым количеством раз. В Vue Test Utils для этого активно используются шпионы (spies) и моки (mocks) из Jest, а также встроенные методы библиотеки.


Использование jest.fn() для создания шпиона

jest.fn() позволяет создать функцию-заглушку, которая может отслеживать свои вызовы. Такой подход полезен при тестировании методов компонента, обработчиков событий и колбэков:

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

test('вызывает метод handleClick при клике', async () => {
  const handleClick = jest.fn()
  const wrapper = shallowMount(MyButton, {
    methods: { handleClick }
  })

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

  expect(handleClick).toHaveBeenCalled()
  expect(handleClick).toHaveBeenCalledTimes(1)
})

Ключевые моменты:

  • jest.fn() создаёт функцию, которая запоминает все вызовы и переданные аргументы.
  • Проверка toHaveBeenCalledTimes позволяет убедиться в правильном количестве вызовов.
  • Проверка toHaveBeenCalledWith подтверждает корректность переданных параметров.

Замена методов компонента при тестировании

Vue Test Utils предоставляет возможность переопределять методы компонента при монтировании через опцию methods. Это позволяет контролировать вызовы методов, не выполняя их реальной реализации:

const wrapper = shallowMount(MyComponent, {
  methods: {
    fetchData: jest.fn()
  }
})

await wrapper.find('button.fetch').trigger('click')

expect(wrapper.vm.fetchData).toHaveBeenCalled()

Такой подход особенно полезен, когда метод выполняет сетевые запросы или другие побочные эффекты.


Контроль событий с помощью $emit

В Vue методы часто вызываются как реакция на события. Vue Test Utils позволяет отслеживать эмиты события и проверять, были ли они вызваны корректно:

const wrapper = shallowMount(MyComponent)
await wrapper.find('input').setValue('Тест')
await wrapper.find('form').trigger('submit.prevent')

expect(wrapper.emitted('submit')).toBeTruthy()
expect(wrapper.emitted('submit')[0]).toEqual(['Тест'])

Особенности контроля вызовов через события:

  • wrapper.emitted() возвращает объект с массивами аргументов для каждого события.
  • Можно проверить количество вызовов события, его аргументы и последовательность.

Моки и шпионы для зависимостей

Методы компонента часто взаимодействуют с внешними модулями или сервисами. Для контроля вызовов таких зависимостей используют мок-функции:

import api from '@/api'
jest.mock('@/api')

test('вызывает api.fetchData при монтировании', () => {
  const wrapper = shallowMount(MyComponent)
  expect(api.fetchData).toHaveBeenCalled()
})

Принципы использования:

  • jest.mock() заменяет импортируемый модуль на мок-объект.
  • Любой вызов функции мока автоматически фиксируется Jest.
  • Позволяет проверять порядок вызовов, аргументы и количество обращений к API без реальных запросов.

Проверка последовательности вызовов

Иногда важно, чтобы методы вызывались в строго определённой последовательности. Jest предоставляет методы для контроля очередности:

const firstFn = jest.fn()
const secondFn = jest.fn()

firstFn()
secondFn()

expect(firstFn).toHaveBeenCalledBefore(secondFn)

При использовании Vue Test Utils это позволяет тестировать сложные цепочки действий, например, вызов методов при изменении реактивных данных или при взаимодействии с пользователем.


Практические рекомендации

  1. Изолировать тестируемый метод — при необходимости заменить побочные методы моками.
  2. Тщательно проверять аргументы вызова с помощью toHaveBeenCalledWith.
  3. Использовать trigger() для событий вместо ручного вызова методов, чтобы тестировать компонент максимально приближенно к реальному поведению.
  4. Следить за количеством вызовов — это помогает обнаружить лишние повторные вызовы или отсутствие необходимых вызовов.
  5. Комбинировать шпионы и эмиты — позволяет проверять и внутренние методы, и реакцию на события.

Контроль вызовов функций в Vue Test Utils обеспечивает надежность тестов и точное подтверждение корректного поведения компонентов. Сочетание jest.fn(), моков, замены методов и отслеживания событий создаёт гибкую систему для детального анализа функциональности Vue-компонентов.