From 6dba219a43ef18f28b5b922a736cb2d4375ab652 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Sun, 25 Sep 2022 11:58:14 +0200 Subject: [PATCH] [DependencyInjection] Add a section for testing service subscribers --- .../service_subscribers_locators.rst | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst index 72971213618..b2196ba1578 100644 --- a/service_container/service_subscribers_locators.rst +++ b/service_container/service_subscribers_locators.rst @@ -256,7 +256,7 @@ argument of type ``service_locator``: # config/services.yaml services: App\CommandBus: - arguments: + arguments: - !service_locator App\FooCommand: '@app.command_handler.foo' App\BarCommand: '@app.command_handler.bar' @@ -723,4 +723,55 @@ and compose your services with them:: as this will include the trait name, not the class name. Instead, use ``__CLASS__.'::'.__FUNCTION__`` as the service id. +Testing a Service Subscriber +---------------------------- + +When you need to unit test a service subscriber, you can either create a fake +``ServiceLocator``:: + + use Symfony\Component\DependencyInjection\ServiceLocator; + + $container = new class() extends ServiceLocator { + private $services = []; + + public function __construct() + { + parent::__construct([ + 'foo' => function () { + return $this->services['foo'] = $this->services['foo'] ?? new stdClass(); + }, + 'bar' => function () { + return $this->services['bar'] = $this->services['bar'] ?? $this->createBar(); + }, + ]); + } + + private function createBar() + { + $bar = new stdClass(); + $bar->foo = $this->get('foo'); + + return $bar; + } + }; + + $serviceSubscriber = new MyService($container); + // ... + +Or mock it when using ``PHPUnit``:: + + use Psr\Container\ContainerInterface; + + $container = $this->createMock(ContainerInterface::class); + $container->expects(self::any()) + ->method('get') + ->willReturnMap([ + ['foo', $this->createStub(Foo::class)], + ['bar', $this->createStub(Bar::class)], + ]) + ; + + $serviceSubscriber = new MyService($container); + // ... + .. _`Command pattern`: https://en.wikipedia.org/wiki/Command_pattern