Skip to content

Commit

Permalink
Configure mockclient if mock_response_factory has been set on a scope…
Browse files Browse the repository at this point in the history
…d client.

This makes it possible to use different mock response factories on different services and also to easily test services that uses http client endpoints.

It also generates an extra test service http_client.mock_client.$name that can be used to configure the MockHttpClient instance if you want to inject a different responsefactory.
  • Loading branch information
tarjei committed Oct 24, 2023
1 parent fafbbfa commit 5091cc6
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
6.4
---

* Add support for setting mock_response_factory per scoped http client
* Add `HttpClientAssertionsTrait`
* Add `AbstractController::renderBlock()` and `renderBlockView()`
* Add native return type to `Translator` and to `Application::reset()`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,9 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode, callable $e
->variableNode('md5')->end()
->end()
->end()
->scalarNode('mock_response_factory')
->info('The id of the service that should generate mock responses. It should be either an invokable or an iterable.')
->end()
->arrayNode('extra')
->info('Extra options for specific HTTP client')
->normalizeKeys(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2543,18 +2543,30 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
$retryOptions = $scopeConfig['retry_failed'] ?? ['enabled' => false];
unset($scopeConfig['retry_failed']);


$httpClientTransport = new Reference('http_client.transport');

if ($responseFactoryId = $scopeConfig['mock_response_factory'] ?? null) {


$container->register('http_client.mock_client.' . $name, MockHttpClient::class)
->setDecoratedService($httpClientTransport, null, -10) // lower priority than TraceableHttpClient (5)
->setArguments(
$responseFactoryId === true ? [] : [new Reference($responseFactoryId)]);
}

if (null === $scope) {
$baseUri = $scopeConfig['base_uri'];
unset($scopeConfig['base_uri']);

$container->register($name, ScopingHttpClient::class)
->setFactory([ScopingHttpClient::class, 'forBaseUri'])
->setArguments([new Reference('http_client.transport'), $baseUri, $scopeConfig])
->setArguments([$httpClientTransport, $baseUri, $scopeConfig])
->addTag('http_client.client')
;
} else {
$container->register($name, ScopingHttpClient::class)
->setArguments([new Reference('http_client.transport'), [$scope => $scopeConfig], $scope])
->setArguments([$httpClientTransport, [$scope => $scopeConfig], $scope])
->addTag('http_client.client')
;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

$container->loadFromExtension('framework', [
'annotations' => false,
'http_method_override' => false,
'handle_all_throwables' => true,
'php_errors' => ['log' => true],
'http_client' => [
'default_options' => null,
'scoped_clients' => [
'notMocked' => [
'base_uri' => 'https://symfony.com'
],
'mocked' => [
'base_uri' => 'https://symfony.com',
'mock_response_factory' => true,
],
]
],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

$container->loadFromExtension('framework', [
'annotations' => false,
'http_method_override' => false,
'handle_all_throwables' => true,
'php_errors' => ['log' => true],
'http_client' => [
'default_options' => null,
'scoped_clients' => [
'notMocked' => [
'base_uri' => 'https://symfony.com'
],
'mocked' => [
'base_uri' => 'https://symfony.com',
'mock_response_factory' => 'my_response_factory'
],
]
],
]);
Original file line number Diff line number Diff line change
Expand Up @@ -2096,9 +2096,44 @@ public function testMailerWithSpecificMessageBus()
$this->assertEquals(new Reference('app.another_bus'), $container->getDefinition('mailer.mailer')->getArgument(1));
}

public function testHttpClientMockResponseFactory()
public function testHttpClientMockResponseFactoryNoService()
{
$container = $this->createContainerFromFile('http_client_mock_response_factory');
$container = $this->createContainerFromFile('http_client_scoped_mock_response_factory');

$notMocked = $container->getDefinition('http_client.mock_client.notMocked');

$this->assertNotSame(MockHttpClient::class, $notMocked->getClass());

$definition = $container->getDefinition('http_client.mock_client.mocked');

$this->assertSame(MockHttpClient::class, $definition->getClass());
$this->assertCount(0, $definition->getArguments());

}

public function testHttpClientMockResponseFactoryWithService()
{
$container = $this->createContainerFromFile('http_client_scoped_mock_response_factory_service');

$notMocked = $container->getDefinition('http_client.mock_client.notMocked');

$this->assertNotSame(MockHttpClient::class, $notMocked->getClass());

$definition = $container->getDefinition('http_client.mock_client.mocked');

$this->assertSame(MockHttpClient::class, $definition->getClass());
$this->assertCount(1, $definition->getArguments());

$argument = $definition->getArgument(0);

$this->assertInstanceOf(Reference::class, $argument);
$this->assertSame('http_client.transport', current($definition->getDecoratedService()));
$this->assertSame('my_response_factory', (string) $argument);
}

public function testHttpClientScopedMockResponseFactory()
{
$container = $this->createContainerFromFile('http_client_scoped_mock_response_factory');

$definition = $container->getDefinition('http_client.mock_client');

Expand Down

0 comments on commit 5091cc6

Please sign in to comment.