bug #37966 [HttpClient][MockHttpClient][DX] Throw when the response factory callable does not return a valid response (fancyweb)

This PR was merged into the 4.4 branch.

Discussion
----------

[HttpClient][MockHttpClient][DX] Throw when the response factory callable does not return a valid response

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

The current message is `TypeError: Argument 4 passed to Symfony\Component\HttpClient\Response\MockResponse::fromRequest() must implement interface Symfony\Contracts\HttpClient\ResponseInterface, instance of Generator given`.

I lost some time with this because I was passing a callable that returns a \Generator instead of passing the resulting \Generator directly. We could support that case but I guess with the added exception message, it is clear we don't support it at all.

Commits
-------

564dce39f8 [HttpClient][MockHttpClient][DX] Throw when the response factory callable does not return a valid response
This commit is contained in:
Fabien Potencier 2020-08-30 08:55:38 +02:00
commit 4d6ea775b7
2 changed files with 46 additions and 0 deletions

View File

@ -68,6 +68,10 @@ class MockHttpClient implements HttpClientInterface
$this->responseFactory->next();
}
if (!$response instanceof ResponseInterface) {
throw new TransportException(\sprintf('The response factory passed to MockHttpClient must return/yield an instance of ResponseInterface, "%s" given.', \is_object($response) ? \get_class($response) : \gettype($response)));
}
return MockResponse::fromRequest($method, $url, $options, $response);
}

View File

@ -22,6 +22,48 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
class MockHttpClientTest extends HttpClientTestCase
{
/**
* @dataProvider validResponseFactoryProvider
*/
public function testValidResponseFactory($responseFactory)
{
(new MockHttpClient($responseFactory))->request('GET', 'https://foo.bar');
$this->addToAssertionCount(1);
}
public function validResponseFactoryProvider()
{
return [
[static function (): MockResponse { return new MockResponse(); }],
[new MockResponse()],
[[new MockResponse()]],
[new \ArrayIterator([new MockResponse()])],
[null],
[(static function (): \Generator { yield new MockResponse(); })()],
];
}
/**
* @dataProvider invalidResponseFactoryProvider
*/
public function testInvalidResponseFactory($responseFactory, string $expectedExceptionMessage)
{
$this->expectException(TransportException::class);
$this->expectExceptionMessage($expectedExceptionMessage);
(new MockHttpClient($responseFactory))->request('GET', 'https://foo.bar');
}
public function invalidResponseFactoryProvider()
{
return [
[static function (): \Generator { yield new MockResponse(); }, 'The response factory passed to MockHttpClient must return/yield an instance of ResponseInterface, "Generator" given.'],
[static function (): array { return [new MockResponse()]; }, 'The response factory passed to MockHttpClient must return/yield an instance of ResponseInterface, "array" given.'],
[(static function (): \Generator { yield 'ccc'; })(), 'The response factory passed to MockHttpClient must return/yield an instance of ResponseInterface, "string" given.'],
];
}
protected function getHttpClient(string $testCase): HttpClientInterface
{
$responses = [];