Skip to content

Commit 5fd1b32

Browse files
committed
Configure mockclient if mock_response_factory has been set on a scoped 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. We also change the framework.http_client.mock_client_factory attribute to allow for a boolean so you can just mock without injecting a responsefactory in the service setup.
1 parent 9b323c6 commit 5fd1b32

17 files changed

+203
-9
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ CHANGELOG
5151
6.4
5252
---
5353

54+
* Add support for setting mock_response_factory per scoped http client
5455
* Add `HttpClientAssertionsTrait`
5556
* Add `AbstractController::renderBlock()` and `renderBlockView()`
5657
* Add native return type to `Translator` and to `Application::reset()`

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1867,7 +1867,7 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode, callable $e
18671867
->end()
18681868
->end()
18691869
->scalarNode('mock_response_factory')
1870-
->info('The id of the service that should generate mock responses. It should be either an invokable or an iterable.')
1870+
->info('The id of the service that should generate mock responses. It should be either an invokable or an iterable or a boolean to just inject the mock client.')
18711871
->end()
18721872
->arrayNode('scoped_clients')
18731873
->useAttributeAsKey('name')
@@ -2006,6 +2006,9 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode, callable $e
20062006
->variableNode('md5')->end()
20072007
->end()
20082008
->end()
2009+
->scalarNode('mock_response_factory')
2010+
->info('The id of the service that should generate mock responses. It should be either an invokable or an iterable or a boolean to just inject the mock client.')
2011+
->end()
20092012
->arrayNode('extra')
20102013
->info('Extra options for specific HTTP client')
20112014
->normalizeKeys(false)

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,18 +2468,27 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
24682468
$retryOptions = $scopeConfig['retry_failed'] ?? ['enabled' => false];
24692469
unset($scopeConfig['retry_failed']);
24702470

2471+
$httpClientTransport = new Reference('http_client.transport');
2472+
2473+
if ($responseFactoryId = $scopeConfig['mock_response_factory'] ?? null) {
2474+
$container->register('http_client.mock_client.'.$name, MockHttpClient::class)
2475+
->setDecoratedService($httpClientTransport, null, -10) // lower priority than TraceableHttpClient (5)
2476+
->setArguments(
2477+
true === $responseFactoryId ? [] : [new Reference($responseFactoryId)]);
2478+
}
2479+
24712480
if (null === $scope) {
24722481
$baseUri = $scopeConfig['base_uri'];
24732482
unset($scopeConfig['base_uri']);
24742483

24752484
$container->register($name, ScopingHttpClient::class)
24762485
->setFactory([ScopingHttpClient::class, 'forBaseUri'])
2477-
->setArguments([new Reference('http_client.transport'), $baseUri, $scopeConfig])
2486+
->setArguments([$httpClientTransport, $baseUri, $scopeConfig])
24782487
->addTag('http_client.client')
24792488
;
24802489
} else {
24812490
$container->register($name, ScopingHttpClient::class)
2482-
->setArguments([new Reference('http_client.transport'), [$scope => $scopeConfig], $scope])
2491+
->setArguments([$httpClientTransport, [$scope => $scopeConfig], $scope])
24832492
->addTag('http_client.client')
24842493
;
24852494
}
@@ -2521,7 +2530,7 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
25212530
if ($responseFactoryId = $config['mock_response_factory'] ?? null) {
25222531
$container->register('http_client.mock_client', MockHttpClient::class)
25232532
->setDecoratedService('http_client.transport', null, -10) // lower priority than TraceableHttpClient (5)
2524-
->setArguments([new Reference($responseFactoryId)]);
2533+
->setArguments(true === $responseFactoryId ? [] : [new Reference($responseFactoryId)]);
25252534
}
25262535
}
25272536

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@
697697
<xsd:attribute name="local-pk" type="xsd:string" />
698698
<xsd:attribute name="passphrase" type="xsd:string" />
699699
<xsd:attribute name="ciphers" type="xsd:string" />
700+
<xsd:attribute name="mock_response_factory" type="xsd:string" />
700701
<xsd:attribute name="rate-limiter" type="xsd:string" />
701702
</xsd:complexType>
702703

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/http_client_mock_response_factory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
'php_errors' => ['log' => true],
88
'http_client' => [
99
'default_options' => null,
10-
'mock_response_factory' => 'my_response_factory',
10+
'mock_response_factory' => true,
1111
],
1212
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'annotations' => false,
5+
'http_method_override' => false,
6+
'handle_all_throwables' => true,
7+
'php_errors' => ['log' => true],
8+
'http_client' => [
9+
'default_options' => null,
10+
'mock_response_factory' => 'my_response_factory',
11+
],
12+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'annotations' => false,
5+
'http_method_override' => false,
6+
'handle_all_throwables' => true,
7+
'php_errors' => ['log' => true],
8+
'http_client' => [
9+
'default_options' => null,
10+
'scoped_clients' => [
11+
'notMocked' => [
12+
'base_uri' => 'https://symfony.com'
13+
],
14+
'mocked' => [
15+
'base_uri' => 'https://symfony.com',
16+
'mock_response_factory' => true,
17+
],
18+
]
19+
],
20+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'annotations' => false,
5+
'http_method_override' => false,
6+
'handle_all_throwables' => true,
7+
'php_errors' => ['log' => true],
8+
'http_client' => [
9+
'default_options' => null,
10+
'scoped_clients' => [
11+
'notMocked' => [
12+
'base_uri' => 'https://symfony.com'
13+
],
14+
'mocked' => [
15+
'base_uri' => 'https://symfony.com',
16+
'mock_response_factory' => 'my_response_factory'
17+
],
18+
]
19+
],
20+
]);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/http_client_mock_response_factory.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<framework:config http-method-override="false" handle-all-throwables="true">
99
<framework:annotations enabled="false" />
1010
<framework:php-errors log="true" />
11-
<framework:http-client mock-response-factory="my_response_factory">
11+
<framework:http-client mock-response-factory="true">
1212
<framework:default-options />
1313
</framework:http-client>
1414
</framework:config>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config http-method-override="false" handle-all-throwables="true">
9+
<framework:annotations enabled="false" />
10+
<framework:php-errors log="true" />
11+
<framework:http-client mock-response-factory="my_response_factory">
12+
<framework:default-options />
13+
</framework:http-client>
14+
</framework:config>
15+
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config http-method-override="false" handle-all-throwables="true">
9+
<framework:annotations enabled="false" />
10+
<framework:php-errors log="true" />
11+
<framework:http-client mock-response-factory="my_response_factory">
12+
<framework:default-options />
13+
<framework:scoped-client name="notMocked" base-uri="https://symfony.com" />
14+
<framework:scoped-client name="mocked" base-uri="https://symfony.com" mock_response_factory="true" />
15+
</framework:http-client>
16+
</framework:config>
17+
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
<framework:config http-method-override="false" handle-all-throwables="true">
8+
<framework:annotations enabled="false" />
9+
<framework:php-errors log="true" />
10+
<framework:http-client mock-response-factory="my_response_factory">
11+
<framework:default-options />
12+
<framework:scoped-client name="notMocked" base-uri="https://symfony.com" />
13+
<framework:scoped-client name="mocked" base-uri="https://symfony.com" mock_response_factory="my_response_factory" />
14+
</framework:http-client>
15+
</framework:config>
16+
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/http_client_mock_response_factory.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ framework:
66
log: true
77
http_client:
88
default_options: ~
9-
mock_response_factory: my_response_factory
9+
mock_response_factory: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
framework:
2+
annotations: false
3+
http_method_override: false
4+
handle_all_throwables: true
5+
php_errors:
6+
log: true
7+
http_client:
8+
default_options: ~
9+
mock_response_factory: my_response_factory
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
framework:
2+
annotations: false
3+
http_method_override: false
4+
handle_all_throwables: true
5+
php_errors:
6+
log: true
7+
http_client:
8+
default_options: ~
9+
mock_response_factory: ~
10+
11+
scoped_clients:
12+
notMocked:
13+
base_uri: https://symfony.com
14+
mocked:
15+
base_uri: https://symfony.com
16+
mock_response_factory: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
framework:
2+
annotations: false
3+
http_method_override: false
4+
handle_all_throwables: true
5+
php_errors:
6+
log: true
7+
http_client:
8+
default_options: ~
9+
mock_response_factory: ~
10+
11+
scoped_clients:
12+
notMocked:
13+
base_uri: https://symfony.com
14+
mocked:
15+
base_uri: https://symfony.com
16+
mock_response_factory: "my_response_factory"

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,9 +2095,38 @@ public function testMailerWithSpecificMessageBus()
20952095
$this->assertEquals(new Reference('app.another_bus'), $container->getDefinition('mailer.mailer')->getArgument(1));
20962096
}
20972097

2098-
public function testHttpClientMockResponseFactory()
2098+
public function testHttpClientMockResponseFactoryNoService()
20992099
{
2100-
$container = $this->createContainerFromFile('http_client_mock_response_factory');
2100+
$container = $this->createContainerFromFile('http_client_scoped_mock_response_factory');
2101+
2102+
$this->assertFalse($container->hasDefinition('http_client.mock_client.notMocked'));
2103+
2104+
$definition = $container->getDefinition('http_client.mock_client.mocked');
2105+
2106+
$this->assertSame(MockHttpClient::class, $definition->getClass());
2107+
$this->assertCount(0, $definition->getArguments());
2108+
}
2109+
2110+
public function testHttpClientMockResponseFactoryWithService()
2111+
{
2112+
$container = $this->createContainerFromFile('http_client_scoped_mock_response_factory_service');
2113+
$this->assertFalse($container->hasDefinition('http_client.mock_client.notMocked'));
2114+
2115+
$definition = $container->getDefinition('http_client.mock_client.mocked');
2116+
2117+
$this->assertSame(MockHttpClient::class, $definition->getClass());
2118+
$this->assertCount(1, $definition->getArguments());
2119+
2120+
$argument = $definition->getArgument(0);
2121+
2122+
$this->assertInstanceOf(Reference::class, $argument);
2123+
$this->assertSame('http_client.transport', current($definition->getDecoratedService()));
2124+
$this->assertSame('my_response_factory', (string) $argument);
2125+
}
2126+
2127+
public function testHttpClientMockResponseFactoryService()
2128+
{
2129+
$container = $this->createContainerFromFile('http_client_mock_response_factory_service');
21012130

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

@@ -2111,6 +2140,16 @@ public function testHttpClientMockResponseFactory()
21112140
$this->assertSame('my_response_factory', (string) $argument);
21122141
}
21132142

2143+
public function testHttpClientUseMockResponseFactory()
2144+
{
2145+
$container = $this->createContainerFromFile('http_client_mock_response_factory');
2146+
2147+
$definition = $container->getDefinition('http_client.mock_client');
2148+
2149+
$this->assertSame(MockHttpClient::class, $definition->getClass());
2150+
$this->assertCount(0, $definition->getArguments());
2151+
}
2152+
21142153
public function testRegisterParameterCollectingBehaviorDescribingTags()
21152154
{
21162155
$container = $this->createContainerFromFile('default_config');

0 commit comments

Comments
 (0)