AAA паттерн (Arrange, Act, Assert)

AAA (Arrange, Act, Assert) — это структурированный подход к написанию тестов, позволяющий сделать их более читаемыми, предсказуемыми и легко поддерживаемыми. В контексте Vue Test Utils этот паттерн помогает организовать тесты компонентов Vue так, чтобы четко разграничить подготовку данных, выполнение действий и проверку результатов.


Arrange — подготовка тестовой среды

На этом этапе создаются все необходимые объекты, моки, стейты и компоненты. Для Vue это обычно включает в себя:

  1. Монтирование компонента Используется функция mount или shallowMount из Vue Test Utils:

    import { mount } from '@vue/test-utils'
    import MyComponent from '@/components/MyComponent.vue'
    
    const wrapper = mount(MyComponent, {
      props: { title: 'Тестовый заголовок' },
      global: {
        mocks: { $t: (msg) => msg } // пример мокирования i18n
      }
    })

    Важно выбрать между mount и shallowMount в зависимости от необходимости рендерить дочерние компоненты.

  2. Подготовка входных данных и состояния Стейт Vuex, пропсы и локальные данные компонента должны быть определены заранее:

    const wrapper = mount(MyComponent, {
      props: { count: 5 },
      data() {
        return { isVisible: true }
      }
    })
  3. Создание моков и заглушек функций Любые методы, события или внешние зависимости компонента необходимо изолировать:

    const mockMethod = jest.fn()
    const wrapper = mount(MyComponent, {
      methods: { handleClick: mockMethod }
    })

Act — выполнение действия

На этом этапе выполняется действие, которое тест должен проверить. В Vue это чаще всего взаимодействие с компонентом или вызов его методов:

  1. Взаимодействие с DOM События, такие как клики или ввод текста:

    await wrapper.find('button').trigger('click')
    await wrapper.find('input').setValue('новое значение')

    await обязателен при работе с асинхронными реактивными обновлениями, чтобы корректно дождаться изменения DOM.

  2. Вызов методов компонента напрямую Можно протестировать бизнес-логику без взаимодействия с DOM:

    wrapper.vm.increment()
  3. Изменение стейта или пропсов Для проверки реактивности:

    await wrapper.setProps({ count: 10 })
    await wrapper.setData({ isVisible: false })

Assert — проверка результата

На этом этапе проверяются эффекты действий. Vue Test Utils предоставляет множество методов для валидации состояния компонента и его DOM:

  1. Проверка рендеринга DOM

    expect(wrapper.text()).toContain('Тестовый заголовок')
    expect(wrapper.find('button').exists()).toBe(true)
  2. Проверка реактивных данных и пропсов

    expect(wrapper.vm.count).toBe(10)
    expect(wrapper.props('count')).toBe(10)
  3. Проверка вызова методов и событий

    const mockMethod = jest.fn()
    wrapper.vm.handleClick()
    expect(mockMethod).toHaveBeenCalled()
  4. Проверка эмита событий

    await wrapper.find('button').trigger('click')
    expect(wrapper.emitted()).toHaveProperty('update')
    expect(wrapper.emitted('update')[0]).toEqual([5])

Примеры использования AAA в Vue Test Utils

Тест компонента с кнопкой и счетчиком

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

test('увеличение счетчика по клику', async () => {
  // Arrange
  const wrapper = mount(Counter, {
    props: { initialCount: 0 }
  })

  // Act
  await wrapper.find('button.increment').trigger('click')

  // Assert
  expect(wrapper.text()).toContain('1')
  expect(wrapper.vm.count).toBe(1)
})

Тест формы с валидацией

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

test('отображение ошибки при пустом вводе', async () => {
  // Arrange
  const wrapper = mount(LoginForm)

  // Act
  await wrapper.find('form').trigger('submit.prevent')

  // Assert
  expect(wrapper.find('.error-message').text()).toBe('Поле обязательно')
})

Рекомендации по применению AAA

  • Каждый тест должен четко следовать трём шагам: подготовка → действие → проверка.
  • Избегать смешивания логики Arrange и Act. Например, не изменять состояние компонента после события в том же блоке, где создается монтированный wrapper.
  • Использовать await при любых реактивных изменениях или асинхронных действиях.
  • Придерживаться AAA повышает читаемость и упрощает поддержку тестов при росте проекта.

AAA-паттерн в сочетании с Vue Test Utils создаёт устойчивый каркас для комплексного тестирования компонентов, позволяя минимизировать баги и улучшить предсказуемость результатов.