Получи случайную криптовалюту за регистрацию!

Как вы пишете тесты на штуковины, которые внутри имеют кучу ас | Саша говорит

Как вы пишете тесты на штуковины, которые внутри имеют кучу асинхронщины и совершают какие-то действия неявно?

Проблема такая:

Дёргаем ручку, которая стартует некий процесс
Ждём пока не произойдут какие-то действия (например, оно сделает два внешних запроса)
Как понять, что после того как мы дождёмся ожидаемых действий код не делает каких-то дополнительных, которых быть не должно?

Можно, конечно, воткнуть какой-нибудь десятисекундный таймаут и подождать после завершения теста. Но во-первых это их замедлит (а тесты должны быть быстрыми), во-вторых код возможно сделает что-то через 15 секунд.

У себя решаю это объектом индикации работы, который имеют практически все такие асинхронные обработчики. Когда что-то начали делать — зарегистрировали таск в этом объекте. Когда закончили — финишировали его. Если счётчик текущих задач больше нуля значит что-то ещё происходит. Плюс возможность подписки на изменения этого статуса, объединения нескольких статусов в один.

Тогда получается что у всего приложения есть состояние «я ещё что-то делаю». С ним тесты писать становится куда приятнее. Мы не ждём N определённых событий, мы дёргаем что нам нужно, дожидаемся пока система скажет что она в idle-режиме, после чего смотрим, что она в итоге сделала.

И очень раздражает, когда берёшь библиотеку/фреймворк, он обладает таким поведением (умеет внутри делать асинхронщину, про которую никак не говорит наружу), но узнать, занят ли он какой-нибудь полезной работой в данный момент нельзя.

Пример — фреймворк для телеграм-ботов telegraf. Я могу сделать инстанс бота, дать ему урл фейкового телеграма (где поднимаю свой моковый сервер ботового телеграм-апи), вызвать метод «держи апдейт, обработай». Но сколько мне затем нужно подождать после этого чтобы взглянуть на массивчики сообщений которые бот отправил — непонятно. Ибо внутри обработчики выполняются в цепочках промисов, которые разбиты отдельными асинхронными операциями самой бизнес-логики.

Для этого кейса пришлось выкинуть использование библиотечной логики middlewares, обработчиков команд и написать вместо этого своё, которое умеет говорить, когда собственно обработка всех событий завершена и больше ничего происходить не будет.