Ответ вслух Middle Тестирование обновлено

Нестабильный асинхронный тест

Вопрос

Тест компонента с загрузкой данных иногда падает, а в консоли предупреждение «not wrapped in act». Как будешь разбираться?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Предупреждение про act почти всегда значит, что компонент ещё обновляется, когда тест уже сделал проверку или закончился. Например, ответ запроса пришёл позже, и setState случился вне ожидания.

Что должно прозвучать в ответе

  • Предупреждение значит: компонент обновился после окончания теста или вне ожидания

  • Жду результат через `findBy` или `waitFor`, а не `getBy` сразу

  • Проверяю, что все действия `user-event` с `await`

  • Убираю побочные действия из колбэка `waitFor`

  • Делаю ответы сети детерминированными через MSW, без реального API

  • Проверяю общие моки и состояние между тестами, сбрасываю обработчики после каждого теста

Что могут спросить следом

  • Почему не стоит просто увеличить таймаут?
  • Как тестировать debounce?
  • Когда всё же нужно вызвать act вручную?

Разбор

Предупреждение про act почти всегда значит, что компонент ещё обновляется, когда тест уже сделал проверку или закончился. Например, ответ запроса пришёл позже, и setState случился вне ожидания.

Сначала проверяю, что тест ждёт результат: вместо getBy сразу после рендера использую await findBy или waitFor с проверкой. Затем смотрю на действия: у user.click и user.type должен быть await. В waitFor должна быть только проверка, иначе действие повторится несколько раз.

Дальше делаю ответы сети детерминированными через MSW и сбрасываю обработчики после каждого теста, чтобы один тест не влиял на другой. Если в коде есть таймеры, включаю фейковые часы и настраиваю user-event через advanceTimers.

Увеличивать таймаут не стану: это прячет проблему и замедляет набор тестов.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.