← Назад к вопросам

Как протестировать API-запрос сервис-клиента?

1.7 Middle🔥 171 комментариев
#API и веб-протоколы#Тестирование

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подход к тестированию API-запросов сервис-клиента

Тестирование API-запросов сервис-клиента — критически важная задача для обеспечения надежности интеграций с внешними сервисами. Я использую многоуровневый подход, сочетающий различные типы тестов для максимального покрытия.

Основные стратегии тестирования

1. Юнит-тестирование с моками и стабами На этом уровне мы изолируем сервис-клиент от реального API, подменяя HTTP-слой:

<?php

use PHPUnit\Framework\TestCase;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;

class ApiClientTest extends TestCase
{
    public function testGetUserData()
    {
        // Создаем мок-ответ
        $mockResponse = json_encode(['id' => 1, 'name' => 'John']);
        
        // Настраиваем мок-клиент Guzzle
        $mockHandler = new MockHandler([
            new Response(200, ['Content-Type' => 'application/json'], $mockResponse)
        ]);
        
        $handlerStack = HandlerStack::create($mockHandler);
        $httpClient = new Client(['handler' => $handlerStack]);
        
        // Создаем тестируемый клиент с мок-зависимостью
        $apiClient = new UserApiClient($httpClient);
        $result = $apiClient->getUser(1);
        
        $this->assertEquals('John', $result['name']);
        $this->assertEquals(200, $apiClient->getLastStatusCode());
    }
}

2. Интеграционные тесты с тестовым окружением Для проверки реального взаимодействия с API используем тестовое окружение:

<?php

class UserApiClientIntegrationTest extends TestCase
{
    private $apiClient;
    
    protected function setUp(): void
    {
        // Используем тестовые учетные данные
        $baseUri = getenv('TEST_API_BASE_URL');
        $apiKey = getenv('TEST_API_KEY');
        
        $this->apiClient = new UserApiClient($baseUri, $apiKey);
    }
    
    public function testRealApiConnection()
    {
        // Тест с реальным, но тестовым API
        $response = $this->apiClient->getUser('test_user_123');
        
        $this->assertArrayHasKey('id', $response);
        $this->assertNotEmpty($response['email'] ?? null);
    }
}

Ключевые аспекты для тестирования

Покрытие различных сценариев:

  • Успешные запросы (200, 201)
  • Ошибки клиента (4xx: 400, 401, 403, 404, 429)
  • Ошибки сервера (5xx: 500, 502, 503)
  • Таймауты и сетевые проблемы
  • Невалидные JSON-ответы
  • Ответы с неожиданной структурой

Тестирование повторных попыток (retry logic):

<?php

public function testRetryOnServerError()
{
    $mockHandler = new MockHandler([
        new Response(500), // Первый запрос падает
        new Response(500), // Второй запрос падает
        new Response(200, [], json_encode(['status' => 'ok'])) // Третий успешен
    ]);
    
    $client = new Client([
        'handler' => HandlerStack::create($mockHandler),
        'retries' => 3
    ]);
    
    $apiClient = new UserApiClient($client);
    
    // Этот вызов должен выдержать 2 неудачи и добиться успеха
    $result = $apiClient->getUser(1);
    
    $this->assertEquals('ok', $result['status']);
}

Инструменты и библиотеки

Основной стек для PHP:

  • PHPUnit — основной фреймворк для тестирования
  • Guzzle MockHandler — для мокинга HTTP-запросов
  • PHP-VCR — для записи и воспроизведения реальных API-запросов
  • Mockery или Prophecy — для создания сложных мок-объектов

Практические рекомендации

  1. Используйте конфигурацию через окружение — отделяйте тестовые и продакшен-ключи API
  2. Создайте фабрику для клиента — упростите создание клиентов с разными конфигурациями
  3. Тестируйте edge cases — пустые ответы, максимально длинные поля, спецсимволы
  4. Версионируйте тестовые данные — синхронизируйте с изменениями в реальном API
  5. Измеряйте покрытие (code coverage) — стремитесь к 80%+ для критических методов
  6. Автоматизируйте в CI/CD — запускайте тесты при каждом коммите

Пример комплексного теста

<?php

class ApiClientComprehensiveTest extends TestCase
{
    /**
     * @dataProvider apiErrorProvider
     */
    public function testErrorHandling($statusCode, $expectedException)
    {
        $mockHandler = new MockHandler([
            new Response($statusCode)
        ]);
        
        $this->expectException($expectedException);
        
        $client = new UserApiClient(new Client([
            'handler' => HandlerStack::create($mockHandler)
        ]));
        
        $client->getUser(1);
    }
    
    public function apiErrorProvider(): array
    {
        return [
            [400, BadRequestException::class],
            [401, UnauthorizedException::class],
            [403, ForbiddenException::class],
            [404, NotFoundException::class],
            [429, RateLimitException::class],
            [500, ServerException::class],
        ];
    }
}

Важность: Хорошо протестированный сервис-клиент предотвращает сбои в продакшене, уменьшает время отладки и повышает устойчивость приложения к внешним сбоям. Инвестиции в качественное тестирование API-клиентов многократно окупаются при масштабировании системы.

Как протестировать API-запрос сервис-клиента? | PrepBro