8000 feature #36487 [HttpClient] Add MockResponse::getRequestMethod() and … · symfony/symfony@d8082fa · GitHub
[go: up one dir, main page]

Skip to content

Commit d8082fa

Browse files
committed
feature #36487 [HttpClient] Add MockResponse::getRequestMethod() and getRequestUrl() to allow inspecting which request has been sent (javespi)
This PR was merged into the 5.2-dev branch. Discussion ---------- [HttpClient] Add MockResponse::getRequestMethod() and getRequestUrl() to allow inspecting which request has been sent | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | - <!-- prefix each issue number with "Fix #", if any --> | License | MIT | Doc PR | - <!-- required for new features --> <!-- Replace this notice by a short README for your feature/bugfix. This will help people understand your PR and can be used as a start for the documentation. Additionally (see https://symfony.com/releases): - Always add tests and ensure they pass. - Never break backward compatibility (see https://symfony.com/bc). - Bug fixes must be submitted against the lowest maintained branch where they apply (lowest branches are regularly merged to upper ones so they get the fixes too.) - Features and deprecations must be submitted against branch master. --> --- As same as the `MockResponse` class has `getRequestOptions()` when doing a request; I've added: * `getRequestUrl()` - returns the URL used when doing the request * `getRequestMethod()` - returns the HTTP method used when doing the request With these two getters, we would be able to assert that the method and URL passed to the `HttpClient` were well generated. I've tried to assert the URL generated in a unit test of a class with a `SymfonyHttpClient` injected and it wasn't possible. Calling `$mock->getInfo('url')` returns `null`. Example, if we have a class with `HttpClientInterface` injected like this: ```php final class SymfonyHttpUserClient { private HttpClientInterface $httpClient; private string $baseUri; public function __construct( HttpClientInterface $httpClient, string $baseUri ) { $this->httpClient = $httpClient; $this->baseUri = $baseUri; } public function getById(string $userId): void { $this->httpClient->request( 'GET', $this->baseUri . $customerId ); } } ``` And if we want to do a unit test of `SymfonyHttpUserClient` right now we are not able to check if the URL of the request was well-formed passing a `MockResponse`. Also, we weren't able to assert the HTTP method (maybe this piece is not so critical to assert in the unit test). ```php class SymfonyHttpUserClientTests extends TestCase { public function testGetById(): void { $baseUri = 'https://user-api.test/api/v1/users/'; $mockResponse = new MockResponse(); $symfonyHttpUserClient = new SymfonyHttpUserClient( new MockHttpClient( [$mockResponse], $baseUri ), $baseUri ); // test get by id: $symfonyHttpUserClient->getById('some-user-id'); // cannot be asserted right now: $this->assertSame($mockResponse->getInfo('url'), $baseUri . 'some-user-id'); // fail $this->assertSame($mockResponse->getInfo('http_method'), 'GET'); // fail // it could be with the new getters: $this->assertSame($mockResponse->getRequestUrl(), $baseUri . 'some-user-id'); $this->assertSame($mockResponse->getRequestMethod(), 'GET'); } } ``` This only happens if the class has injected the HttpClient and if it is used inside void methods with no being able to return the response. If the class returns the response, `url` and `http_method` are available with `$response->getInfo()` call. But this response object is a new one, is not the mock passed by argument when you instance the MockHttpClient. Var dumps of `getInfo` array: ``` $response->getInfo() from MockClient: ..array(10) { ["start_time"]=> float(1587109014.7985) ["user_data"]=> NULL ["http_code"]=> int(200) ["response_headers"]=> array(0) { } ["error"]=> NULL ["canceled"]=> bool(false) ["redirect_count"]=> int(0) ["redirect_url"]=> NULL ["http_method"]=> string(3) "GET" ["url"]=> string(47) "https://user-api.test/api/v1/users/some-user-id" } $mock->getInfo() array(4) { ["http_code"]=> int(200) ["response_headers"]=> array(0) { } ["error"]=> NULL ["canceled"]=> bool(false) } ``` This is a minor change, I opened the PR with `4.4` as base branch; but not sure if it should be opened with `5.0` as base branch or even `master` taking account is a feature (add two new getters in MockResponse class). Let me know if I didn't follow right the instructions (first PR on Symfony project 😃) Thanks! Commits ------- 7a250d8 [HttpClient] Add MockResponse::getRequestMethod() and getRequestUrl() to allow inspecting which request has been sent
2 parents 501542a + 7a250d8 commit d8082fa

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

src/Symfony/Component/HttpClient/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* added `AsyncDecoratorTrait` to ease processing responses without breaking async
88
* added support for pausing responses with a new `pause_handler` callable exposed as an info item
99
* added `StreamableInterface` to ease turning responses into PHP streams
10+
* added `MockResponse::getRequestMethod()` and `getRequestUrl()` to allow inspecting which request has been sent
1011

1112
5.1.0
1213
-----

src/Symfony/Component/HttpClient/Response/MockResponse.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class MockResponse implements ResponseInterface, StreamableInterface
3232

3333
private $body;
3434
private $requestOptions = [];
35+
private $requestUrl;
36+
private $requestMethod;
3537

3638
private static $mainMulti;
3739
private static $idSequence = 0;
@@ -72,6 +74,22 @@ public function getRequestOptions(): array
7274
return $this->requestOptions;
7375
}
7476

77+
/**
78+
* Returns the URL used when doing the request.
79+
*/
80+
public function getRequestUrl(): string
81+
{
82+
return $this->requestUrl;
83+
}
84+
85+
/**
86+
* Returns the method used when doing the request.
87+
*/
88+
public function getRequestMethod(): string
89+
{
90+
return $this->requestMethod;
91+
}
92+
7593
/**
7694
* {@inheritdoc}
7795
*/
@@ -122,6 +140,8 @@ public static function fromRequest(string $method, string $url, array $options,
122140

123141
if ($mock instanceof self) {
124142
$mock->requestOptions = $response->requestOptions;
143+
$mock->requestMethod = $method;
144+
$mock->requestUrl = $url;
125145
}
126146

127147
self::writeRequest($response, $options, $mock);

src/Symfony/Component/HttpClient/Tests/Response/MockResponseTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ public function testToArrayError($content, $responseHeaders, $message)
3333
$response->toArray();
3434
}
3535

36+
public function testUrlHttpMethodMockResponse(): void
37+
{
38+
$responseMock = new MockResponse(json_encode(['foo' => 'bar']));
39+
$url = 'https://example.com/some-endpoint';
40+
$response = MockResponse::fromRequest('GET', $url, [], $responseMock);
41+
42+
$this->assertSame('GET', $response->getInfo('http_method'));
43+
$this->assertSame('GET', $responseMock->getRequestMethod());
44+
45+
$this->assertSame($url, $response->getInfo('url'));
46+
$this->assertSame($url, $responseMock->getRequestUrl());
47+
}
48+
3649
public function toArrayErrors()
3750
{
3851
yield [

0 commit comments

Comments
 (0)
0