Справжні запити в unit-тестах - повільні, нестабільні й залежать від стану сервера. Їх замінюють, і є два рівні, на яких це роблять.
1. Мок модуля API (vi.mock) - замінити функції, що роблять запити:
import { vi } from 'vitest'
import * as api from '@/api/orders'
vi.mock('@/api/orders', () => ({
fetchOrders: vi.fn(),
}))
it('shows orders', async () => {
vi.mocked(api.fetchOrders).mockResolvedValue([{ id: 1, total: 100 }])
const wrapper = mount(OrdersList)
await flushPromises()
expect(wrapper.text()).toContain('100')
expect(api.fetchOrders).toHaveBeenCalledWith({ status: 'paid' })
})
vi.mock піднімається на початок файлу (hoisting) і діє на всі імпорти модуля в тесті.
- плюси: просто, швидко, видно аргументи виклику;
- мінуси: тест прив'язаний до того, як компонент отримує дані. Перейшли з
fetchOrdersнаuseQuery- треба переписувати моки; помилки у формуванні запиту (URL, заголовки, серіалізація) не перевіряються.
2. Перехоплення мережі (MSW - Mock Service Worker) - компонент робить справжній fetch, а MSW відповідає замість сервера:
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
const server = setupServer(
http.get('/api/orders', () => HttpResponse.json([{ id: 1, total: 100 }])),
)
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
it('shows an error when the API fails', async () => {
server.use(http.get('/api/orders', () => new HttpResponse(null, { status: 500 })))
// ...
})
- плюси: перевіряється весь шлях - URL, параметри, обробка статусів; тест не залежить від того, яким клієнтом зроблено запит; ті самі обробники можна використати в браузері для розробки й у Storybook;
- мінуси: більше налаштувань.
Що обрати: для компонентів, що працюють з HTTP, MSW дає надійніші тести. vi.mock доречний для модулів, які не є HTTP (аналітика, локальне сховище, сторонні SDK), і для швидких точкових перевірок.
Обов'язково тестувати не лише успіх: помилку сервера, порожню відповідь, повільну відповідь (стан завантаження) і помилку валідації 422.
onUnhandledRequest: 'error' - щоб незамоканий запит падав тестом, а не мовчки йшов у мережу.