Тестируйте свой код без сети
PHPИспользуйте тестовый дублёр, который поставляется с SDK, чтобы ставить в очередь ответы API и проверять запросы, которые отправил ваш код.
4 мин чтения
SDK поставляется с тестовым дублёром своего HTTP-клиента. Тест ставит в очередь ответы, которые дал бы API, запускает ваш код на настоящем SDK и читает обратно запросы, которые SDK отправил. Ни один запрос не покидает процесс, а ключом служит любой непустой текст.
Дублёр — FakeHttpClient, в пространстве имён Slen\Sdk\Testing: клиент PSR-18.
Написать тест
1. Поставьте ответ в очередь
Создайте дублёр и поставьте в очередь ответ API: статус и тело, как их отправляет API. Тело успешного ответа обёрнуто в data.
use Slen\Sdk\Testing\FakeHttpClient;
$http = (new FakeHttpClient())->pushJson(200, ['data' => [
'execution_id' => '74438200973594700',
'status' => 'completed',
'operation' => 'generate_email',
'output' => ['content' => 'Hi Ada, just checking in on the proposal I sent last week.'],
'error' => null,
'error_code' => null,
'error_message' => null,
'cost' => ['estimated' => '0.00412500', 'actual' => null],
'cache' => ['hit' => false, 'cached_at' => null],
'replayed' => false,
'waiting_on' => null,
'trace_url' => '/v1/executions/74438200973594700',
]]);2. Дайте дублёр SDK
SDK — настоящий. Заменён только его HTTP-клиент, поэтому тест выполняет тот же код, что и ваше приложение.
use Slen\Sdk\SlenConfig;
use Slen\Sdk\SlenSdk;
$slen = SlenSdk::create(new SlenConfig(apiKey: 'key-for-tests', httpClient: $http));Дублёр — это httpClient конфигурации.
3. Запустите свой код
use Slen\Sdk\Modules\Operations\Options\ExecuteOptions;
$execution = $slen->operations()->execute(
'generate_email',
['messages' => [['role' => 'user', 'content' => 'Write a short follow-up email.']]],
new ExecuteOptions(idempotencyKey: 'order-42:email'),
);4. Проверьте, что ушло
Дублёр записывает каждый запрос: метод, адрес, заголовки и тело.
$sent = $http->lastRequest();
echo $execution->status->value, PHP_EOL;
echo $sent->getMethod(), ' ', $sent->getUri(), PHP_EOL;
echo $sent->getHeaderLine('Idempotency-Key'), PHP_EOL;
echo json_decode((string) $sent->getBody(), true)['operation'], PHP_EOL;lastRequest() возвращает последний запрос, а requests() — все, как запросы PSR-7.
Ответы выдаются в порядке очереди
Каждый запрос берёт следующий ответ из очереди. Ставьте в очередь по ответу на каждый запрос, который делает ваш код.
Дублёр строгий. Запрос, для которого в очереди нет ответа, проваливает тест с LogicException, и запрос всё равно записывается. Дублёр, который прощал бы лишний запрос, скрыл бы ту ошибку, ради которой он нужен, — вызов, отправленный дважды.
SDK отправляет запрос ещё раз после 429, 503 или когда ответа не было — столько раз, сколько говорит retries, — Повторы и таймауты. Тест такого ответа ставит в очередь по ответу на каждую попытку или задаёт retries, равное 0, — всему SDK или в опциях одного вызова.
Протестировать ошибку
Поставьте ошибку в очередь так же: её статус и конверт ошибки API. SDK выбрасывает ту ошибку, которую выбросил бы на настоящий ответ. Конверт описывает статья Обзор.
{
"error": {
"code": "flow_not_found",
"message": "No flow is bound to operation \"generate_email\"",
"request_id": "0d3c1b9e-5a47-4f0e-9a36-2f6c8d1e7b42"
}
}pushException() ставит в очередь исключение HTTP-клиента вместо ответа. Сетевое исключение PSR-18 изображает запрос, который остался без ответа, и SDK после него отправляет запрос ещё раз: поставьте по одному на каждую попытку, и SDK выбросит ConnectionException после последней.
Протестировать спаны
RecordingSpanRecorder, переданный в конфигурацию как spanRecorder, держит спаны теста: spans() возвращает их все, а last() — последний, — Спаны.
Что читать дальше
Быстрый старт — вызов, который выполняет тест этой страницы.
Асинхронные запуски и ожидание — ожидание читает статус несколько раз, поэтому его тест ставит в очередь несколько ответов.
Обработка ошибок — какой ошибкой становится каждый ответ.