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

Как тестируешь отправку запросов?

1.7 Middle🔥 111 комментариев
#Тестирование

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

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

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

Подход к тестированию отправки HTTP-запросов в PHP Backend

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

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

1. Модульное тестирование с моками и стабами

Для изоляции бизнес-логики от реальных HTTP-запросов использую мок-объекты:

// Пример теста с PHPUnit и моками
class PaymentServiceTest extends TestCase
{
    public function test_process_payment_sends_correct_request()
    {
        // Создаем мок HTTP-клиента
        $httpClient = $this->createMock(HttpClientInterface::class);
        
        // Ожидаем конкретный запрос
        $httpClient->expects($this->once())
            ->method('post')
            ->with(
                'https://api.payment.com/charge',
                $this->callback(function ($options) {
                    return $options['amount'] === 1000 
                        && $options['currency'] === 'USD';
                })
            )
            ->willReturn(new Response(200, [], '{"status": "success"}'));
        
        $paymentService = new PaymentService($httpClient);
        $result = $paymentService->charge(1000, 'USD');
        
        $this->assertTrue($result->isSuccessful());
    }
}

2. Интеграционное тестирование с реальными сервисами

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

// Интеграционный тест с реальным клиентом
class ExternalApiIntegrationTest extends TestCase
{
    private $testClient;
    
    protected function setUp(): void
    {
        $this->testClient = new HttpClient([
            'base_uri' => $_ENV['TEST_API_URL'],
            'timeout'  => 5,
        ]);
    }
    
    public function test_api_returns_valid_response()
    {
        // Используем тестовые учетные данные
        $response = $this->testClient->post('/auth', [
            'json' => [
                'api_key' => $_ENV['TEST_API_KEY'],
                'action' => 'test'
            ]
        ]);
        
        $this->assertEquals(200, $response->getStatusCode());
        $this->assertJson($response->getBody());
    }
}

Ключевые инструменты и библиотеки

  • PHPUnit — основной фреймворк для модульного и интеграционного тестирования
  • Mockery или встроенные моки PHPUnit — для создания mock-объектов
  • GuzzleHTTP Mock Handler — для тестирования Guzzle-клиентов
  • Symfony HttpClient MockHttpClient — в Symfony-проектах
  • Laravel Http Fake — в Laravel-приложениях для подмены HTTP-запросов

Практические подходы

Тестирование заголовков и параметров

// Проверка заголовков и параметров запроса
public function test_request_headers_and_params()
{
    $mockHandler = new MockHandler([
        new Response(200, ['Content-Type' => 'application/json'])
    ]);
    
    $historyContainer = [];
    $historyMiddleware = Middleware::history($historyContainer);
    
    $client = new Client(['handler' => $historyMiddleware($mockHandler)]);
    $client->get('/endpoint', ['headers' => ['X-Api-Key' => 'test123']]);
    
    // Проверяем отправленные заголовки
    $sentRequest = $historyContainer[0]['request'];
    $this->assertEquals('test123', $sentRequest->getHeaderLine('X-Api-Key'));
}

Тестирование обработки ошибок

// Тестирование сетевых ошибок и таймаутов
public function test_handles_network_failures()
{
    $client = $this->createMock(HttpClientInterface::class);
    
    // Имитируем таймаут
    $client->method('request')
           ->willThrowException(new ConnectException(
               'Connection timeout',
               $this->createMock(RequestInterface::class)
           ));
    
    $service = new ApiService($client);
    
    $this->expectException(ServiceUnavailableException::class);
    $service->fetchData();
}

Организация тестовых данных

  • Использую Data Providers в PHPUnit для параметризованных тестов различных сценариев
  • Создаю фабрики тестовых запросов для повторного использования
  • Храню примеры ответов в фикстурах (JSON/XML файлах)
  • Использую environment variables для конфигурации тестовых окружений

Continuous Integration интеграция

В CI/CD пайплайнах:

  1. Запускаю модульные тесты с моками на каждом коммите
  2. Выполняю интеграционные тесты с тестовыми серверами в отдельных окружениях
  3. Использую Rate Limiting имитацию для тестирования обработки ограничений API
  4. Тестирую retry логику при неудачных запросах

Мониторинг и анализ

  • Логирую все исходящие запросы в тестовом окружении
  • Анализирую покрытие кода, связанного с HTTP-клиентами
  • Использую инструменты типа WireMock для записи и воспроизведения реальных API-ответов

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