Как тестировать асинхронный код и таймеры?
Unit и компонентные тесты
Асинхронный код тестируют, дожидаясь его результата явно, а таймеры подменяют, чтобы не ждать реальное время.
Промисы и async/await
Тест возвращает промис или использует async, а проверки идут после await. Для UI применяют findBy* и waitFor, которые повторяют проверку, пока условие не выполнится.
render(<Users />);
expect(await screen.findByText('Ann')).toBeInTheDocument();Fake timers
vi.useFakeTimers();
const cb = vi.fn();
debounce(cb, 300)();
vi.advanceTimersByTime(299);
expect(cb).not.toHaveBeenCalled();
vi.advanceTimersByTime(1);
expect(cb).toHaveBeenCalledOnce();
vi.useRealTimers();Частые ошибки
- Забыли
await, и тест проходит до выполнения проверки. - Реальные
setTimeoutв тестах замедляют набор и делают его нестабильным. - Не вернули реальные таймеры в
afterEach, и другие тесты ломаются.
Коротко для собеседования
Ждём результат через await, findBy или waitFor, а время подменяем fake timers и двигаем вручную.