При тестировании компонентов Vue часто возникает необходимость проверять поведение приложения при взаимодействии с внешними API. Реальные HTTP-запросы замедляют тесты и делают их нестабильными, поэтому используется подход с перехватом запросов и созданием моков.
Чаще всего в проектах Vue HTTP-запросы выполняются через
axios. Для тестирования удобно подменять его поведение.
Пример настройки мока с Jest:
import { shallowMount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
import axios from 'axios'
jest.mock('axios')
test('должен загрузить данные с API', async () => {
const mockData = { data: { name: 'Vue' } }
axios.get.mockResolvedValue(mockData)
const wrapper = shallowMount(MyComponent)
await wrapper.vm.fetchData() // метод компонента, который вызывает axios.get
expect(wrapper.vm.data).toEqual(mockData.data)
expect(axios.get).toHaveBeenCalledWith('/api/data')
})
Ключевые моменты:
jest.mock('axios') подменяет модуль axios во всех
тестах.mockResolvedValue используется для имитации успешного
ответа.toHaveBeenCalledWith позволяет убедиться, что
запрос отправлен по правильному URL.Если проект использует fetch, его также можно
замокать:
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ name: 'Vue' })
})
)
test('fetch-запрос возвращает данные', async () => {
const wrapper = shallowMount(MyComponent)
await wrapper.vm.loadData()
expect(wrapper.vm.data.name).toBe('Vue')
expect(fetch).toHaveBeenCalledWith('/api/data')
})
Особенности:
global.fetch = jest.fn() подменяет стандартный
fetch.json, text и другие можно
настраивать для имитации различных ответов.fetch.mockClear().msw для более сложных сценариевmsw (Mock Service Worker) позволяет перехватывать
HTTP-запросы на уровне сетевого слоя, что удобно для интеграционных
тестов:
import { setupServer } from 'msw/node'
import { rest } from 'msw'
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
const server = setupServer(
rest.get('/api/data', (req, res, ctx) => {
return res(ctx.json({ name: 'Vue' }))
})
)
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
test('компонент получает данные через msw', async () => {
const wrapper = mount(MyComponent)
await wrapper.vm.fetchData()
expect(wrapper.vm.data.name).toBe('Vue')
})
Преимущества msw:
Тестирование компонентов должно включать сценарии с ошибками:
axios.get.mockRejectedValue(new Error('Network Error'))
test('компонент обрабатывает ошибку запроса', async () => {
const wrapper = shallowMount(MyComponent)
await wrapper.vm.fetchData()
expect(wrapper.vm.error).toBe('Network Error')
})
Важно:
error, loading).Для асинхронных запросов часто требуется управление таймерами:
jest.useFakeTimers()
test('данные загружаются после задержки', async () => {
axios.get.mockImplementation(() =>
new Promise(resolve => setTimeout(() => resolve({ data: { name: 'Vue' } }), 1000))
)
const wrapper = shallowMount(MyComponent)
const promise = wrapper.vm.fetchData()
jest.advanceTimersByTime(1000)
await promise
expect(wrapper.vm.data.name).toBe('Vue')
})
Пояснение:
jest.useFakeTimers() позволяет контролировать
setTimeout и setInterval.jest.advanceTimersByTime ускоряет прохождение
асинхронных операций.jest.mock) или sinon.msw или
аналогичные сервисы для перехвата реальных HTTP-запросов.Каждый подход имеет свои сильные стороны: первые удобны для unit-тестов, вторые — для проверки взаимодействия с API без сетевых вызовов, третьи — для интеграционного тестирования в условиях максимально приближенных к реальности.
mockClear или
resetHandlers.mount вместо
shallowMount, чтобы проверить реактивность и DOM.msw, чтобы
избежать громоздких моков вручную.Перехват и моки HTTP-запросов — ключевой инструмент для надёжного тестирования Vue-компонентов, позволяющий создавать стабильные, быстрые и предсказуемые тесты без обращения к реальным API.