Протестировать ретраи и бэкофф
Мок, который сперва падает, потом отвечает успехом — чтобы проверить логику ретраев.
Код ретраев тяжело тестировать, потому что настоящие API редко падают тогда, когда вам это нужно. Мок с последовательностью ответов это чинит: первый вызов отдаёт 500, следующий — 200, и цикл повторяется. Так вы получаете детерминированный отказ, на который может опереться тест, и можете доказать, что повтор действительно случился и вторая попытка прошла, а не просто предположить это.
Как заставить вызов упасть один раз и затем пройти?
Опишите ответ по умолчанию как отказ, а то, что идёт после него, — через последовательность ответов. Мок проходит её по шагу на вызов и затем начинает заново, поэтому один эндпоинт даёт схему «упал, потом прошёл», нужную любому тесту ретраев, — в фиксированном порядке и без случайности, которая делает тест плавающим.
Детерминизм здесь и есть суть. Тестировать ретраи против по-настоящему нестабильного эндпоинта — значит получить набор тестов, который падает и проходит по причинам, не связанным с вашим кодом. Если случайность всё-таки нужна — для нагрузочного прогона, а не для юнит-теста, — берите долю ошибок, а не последовательность.
Как проверить именно back-off, а не только число попыток?
Счётчик попыток доказывает, что вы повторили, но не доказывает, что вы ждали. Посмотрите в инспекторе время каждой доставки и проверьте, что интервалы растут так, как предписывает ваша политика. Ретраи с фиксированным интервалом от всех клиентов разом — это то, что превращает короткий сбой в затяжной, поэтому стандартный совет — экспоненциальный back-off с джиттером.
Добавьте моку задержку ответа, чтобы проверить вторую половину проблемы: запрос, который висит, а не падает. Клиент с ретраями, но без таймаута будет ждать первую попытку бесконечно и до повтора вообще не дойдёт.
Какие отказы вообще стоит повторять?
Повторять всё так же неправильно, как не повторять ничего. 500 или 503 стоят ещё одной попытки; 400 или 422 будут падать одинаково всегда, и ретрай лишь размножит ошибку. 429 — отдельный случай: тут надо соблюдать заголовок Retry-After, а не применять собственное расписание.
Замокайте каждый из этих случаев отдельным эндпоинтом и проверяйте нужное поведение: повторили, не повторили, отложили до разрешения сервера. Три маленьких мока описывают вашу политику ретраев точнее любого комментария в коде.
С какого-то момента повторы надо прекращать и падать громко. Предохранитель, который размыкается после серии неудач, защищает и вас, и вызываемый сервис: бесконечные повторы превращают чужую недоступность в вашу собственную и заодно прячут её от вашего мониторинга.
Что обычно идёт не так?
- Повторяют неидемпотентные запросы. Повторённый POST может списать деньги дважды. Повторяйте только там, где дубль безвреден, либо используйте ключ идемпотентности.
- Нет потолка. Ретраи без ограничения превращают короткий чужой сбой в ваш собственный длинный.
- Ретрай без таймаута. Если первая попытка никогда не вернётся, повтор никогда не запустится — тестируйте зависание, а не только отказ.
- Синхронные ретраи. Без джиттера все клиенты повторяют в один такт, и по восстанавливающемуся сервису бьёт сразу весь парк.
Когда это нужно
Логику ретраев почти никогда не тестируют — настоящий API не падает по команде. Этот мок отдаёт 500 на первый вызов и 200 на второй, затем повторяет, и автотест может проверить, что клиент ретраит и восстанавливается. Заголовок X-Mockapi-Variant показывает, какой шаг обслужил вызов.
Создать мок
curl -X POST https://quickmock.dev/api/mocks \
-H 'Content-Type: application/json' \
-d '{
"method": "GET",
"response_status": 500,
"content_type": "application/json",
"response_body": "{\"error\":\"upstream\"}",
"response_sequence": [
{ "status": 200, "body": "{\"ok\":true}" }
]
}'
Вызвать
curl https://quickmock.dev/m/<slug>
Что получите
1st call -> 500 (X-Mockapi-Variant: seq-1/2)
2nd call -> 200 (seq-2/2)
...then it cycles
Частые вопросы
- Порядок отказов детерминирован?
- Да. Последовательность ответов проходится по порядку, по шагу на вызов, затем повторяется, поэтому один и тот же тест даёт одну и ту же цепочку статусов на каждом прогоне. Долю ошибок берите только тогда, когда случайность нужна намеренно.
- Как посмотреть, сколько раз клиент повторил запрос?
- Инспектор перечисляет каждую доставку со временем, поэтому число попыток — это число запросов, а back-off — интервалы между ними. Так же ловится клиент, который повторяет заметно чаще, чем задумано.
- Можно ли сымитировать зависший запрос вместо ошибки?
- Да, задайте задержку ответа. Это случай, который пропускает большинство тестов ретраев: клиент без таймаута навсегда встаёт на первой попытке, и его логика повторов не выполняется вовсе.
Собери свой
Создать мокПохожие гайды
Обновлено: 2026-09-08