From e6be0ebca66fbd2540bb4b5989a1468d7844b92d Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Sun, 29 Jan 2023 10:08:33 +0100 Subject: [PATCH] [HttpClient] Allow yielding Exception from MockResponse's $body to mock transport errors --- http_client.rst | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/http_client.rst b/http_client.rst index 360e9b3cfcc..1d61163ebb7 100644 --- a/http_client.rst +++ b/http_client.rst @@ -1214,6 +1214,8 @@ response and get remaining contents that might come back in a new timeout, etc. Use the ``max_duration`` option to limit the time a full request/response can last. +.. _http-client_network-errors: + Dealing with Network Errors ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1975,6 +1977,59 @@ test it in a real application:: } } +Simulate a Transport Exception +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When making HTTP requests, it sometimes occurs an error at transport level. +You can find more information about transport errors it in the +:ref:`Network Errors ` section. + +It may be useful to test how your application behaves in case of a transport +error. :class:`Symfony\\Component\\HttpClient\\Response\\MockResponse` allows +you to do so, by yielding the exception from its body:: + + // ExternalArticleServiceTest.php + use PHPUnit\Framework\TestCase; + use Symfony\Component\HttpClient\MockHttpClient; + use Symfony\Component\HttpClient\Response\MockResponse; + + final class ExternalArticleServiceTest extends TestCase + { + // ... + + public function testTransportLevelError(): void + { + $requestData = ['title' => 'Testing with Symfony HTTP Client']; + $httpClient = new MockHttpClient([ + // You can create the exception directly in the body... + new MockResponse([new \RuntimeException('Error at transport level')]), + + // ... or you can yield the exception from a callback + new MockResponse((static function (): \Generator { + yield new TransportException('Error at transport level'); + })()), + ]); + + $service = new ExternalArticleService($httpClient); + + try { + $service->createArticle($requestData); + + // An exception should have been thrown in `createArticle()`, so this line should never be reached + $this->fail(); + } catch (TransportException $e) { + $this->assertEquals(new \RuntimeException('Error at transport level'), $e->getPrevious()); + $this->assertSame('Error at transport level', $e->getMessage()); + } + } + } + +.. versionadded:: 6.1 + + Being allowed to pass an exception directly to the body of a + :class:`Symfony\\Component\\HttpClient\\Response\\MockResponse` was + introduced in Symfony 6.1. + .. _`cURL PHP extension`: https://www.php.net/curl .. _`Zlib PHP extension`: https://www.php.net/zlib .. _`PSR-17`: https://www.php-fig.org/psr/psr-17/