Внешняя платёжная система в реальности возвращает «ожидание» после первого запроса статуса, а затем «успешно», но мок всегда отвечает «успешно». Какой дефект интеграционного клиента останется незамеченным?
Останется незамеченным дефект обработки переходного состояния: клиент может не уметь корректно распознавать «ожидание», выбирать момент следующей проверки или завершать операцию слишком рано. Мок должен воспроизводить последовательность состояний зависимости, а не возвращать один и тот же успешный ответ при каждом обращении.
Простые моки получили широкое применение как способ изолировать тестируемый компонент от медленных, нестабильных или недоступных внешних систем. Такой мок обычно отвечает заранее заданным результатом и хорошо подходит для проверки одного изолированного сценария.
Однако реальные интеграции часто являются конечными автоматами: результат следующего запроса зависит от предыдущих действий, времени или уже достигнутого состояния. Поэтому появились stateful-моки, фейки и симуляторы, которые воспроизводят допустимые переходы состояния, а не только отдельные ответы.
Платёжная операция может проходить несколько стадий: создана, обрабатывается, успешно завершена или отклонена. Если тестовая зависимость сразу возвращает финальный результат, клиент не проверяется на промежуточных ответах и может ошибочно считать платёж завершённым.
Последствия проявятся только при работе с настоящей системой: преждевременное подтверждение заказа, отсутствие повторной проверки, неправильное отображение статуса или бесконечный цикл опроса. При этом интеграционный тест будет стабильно зелёным, потому что его мок не моделирует требуемое поведение.
Нужно настроить тестовую зависимость так, чтобы результат зависел от истории взаимодействия. Например, первый запрос статуса должен вернуть «ожидание», следующий — «успешно», а отдельный сценарий должен проверять отказ или превышение допустимого числа попыток.
Тест должен проверять не только итоговый статус, но и поведение клиента между состояниями: он не завершает операцию на «ожидании», соблюдает заданную политику повторных запросов, прекращает опрос после финального результата и корректно обрабатывает неизвестное или недопустимое состояние.
Есть несколько способов моделирования:
Модель должна отражать только значимые для клиента переходы, а не копировать всю внешнюю систему. Важно также явно ограничить число повторов и время ожидания, иначе тест может зависнуть при ошибке клиента.
Команда проверяла сервис, который после создания платежа периодически запрашивал его статус. Мок платёжного провайдера на каждый запрос возвращал «успешно», поэтому тест проходил даже после удаления обработки промежуточного статуса.
Рассматривались три варианта. Увеличить число одинаковых успешных ответов было бессмысленно: это не проверяло переходы. Подключить реальный тестовый стенд провайдера было точнее, но сделало прогон медленным и зависимым от внешней среды. В итоге выбрали stateful-мок с последовательностями «ожидание → успешно», «ожидание → отказ» и «ожидание без завершения».
В результате тест выявил, что клиент завершал локальную операцию после первого ответа, отличного от ошибки. Stateful-мок дал воспроизводимый сценарий, а отдельная проверка лимита опроса предотвратила бесконечное ожидание.
Нет. Нужно проверить также условие завершения: второй запрос должен выполняться только в разрешённом состоянии, с заданным ограничением количества попыток или времени. Иначе клиент может формально повторять запрос, но продолжать опрос бесконечно или игнорировать финальный отказ.
Проверка последовательности только фиксирует, какие вызовы сделал клиент. Stateful-мок дополнительно меняет ответ зависимости в соответствии с текущим состоянием и тем самым проверяет реакцию клиента на разные этапы протокола. Одной проверки порядка вызовов недостаточно, если ответы не отражают переходы состояния.
Потому что тест проверяет заранее выбранную модель поведения, а не реальную реализацию провайдера. Он не гарантирует совместимость форматов, корректность сетевых ошибок и соответствие фактической временной семантике внешней системы. Поэтому stateful-моки полезно дополнять контрактными проверками и ограниченным набором тестов против тестового стенда провайдера.