From b05304858c9fba6a64aeef0ea6d9a195305a5297 Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Sat, 4 Apr 2020 15:26:02 +0200 Subject: [PATCH] Introduce a service in the test application that exposes driver's service container --- ...ccessing_drivers_service_container.feature | 20 ++++++--------- ...riendsOfBehatSymfonyExtensionExtension.php | 25 +++++++++++++++++++ src/ServiceContainer/SymfonyExtension.php | 2 +- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/features/mink_integration/accessing_drivers_service_container.feature b/features/mink_integration/accessing_drivers_service_container.feature index 9bbf91c..f923ebb 100644 --- a/features/mink_integration/accessing_drivers_service_container.feature +++ b/features/mink_integration/accessing_drivers_service_container.feature @@ -39,12 +39,12 @@ Feature: Accessing driver's service container final class SomeContext implements Context { private $mink; - private $container; + private $driverContainer; - public function __construct(Mink $mink, ContainerInterface $container) + public function __construct(Mink $mink, ContainerInterface $driverContainer) { $this->mink = $mink; - $this->container = $container; + $this->driverContainer = $driverContainer; } /** @Given the counter service is zeroed */ @@ -67,18 +67,12 @@ Feature: Accessing driver's service container private function getCounterService(): Counter { - return $this->container - ->get('behat.service_container') - ->get('fob_symfony.driver_kernel') - ->getContainer() - ->get('test.service_container') - ->get('App\Counter') - ; + return $this->driverContainer->get('App\Counter'); } } """ - Scenario: Injecting Mink serivce + Scenario: Accessing a service from driver's service container (manually injected dependencies) Given a YAML services file containing: """ services: @@ -86,12 +80,12 @@ Feature: Accessing driver's service container public: true arguments: - '@behat.mink' - - '@service_container' + - '@behat.driver.service_container' """ When I run Behat Then it should pass - Scenario: Autowiring and autoconfiguring Mink service + Scenario: Accessing a service from driver's service container (autowired & autoconfigured dependencies) Given a YAML services file containing: """ services: diff --git a/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php b/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php index abfd109..c014a41 100644 --- a/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php +++ b/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php @@ -8,6 +8,7 @@ use Behat\Behat\Context\Context; use Behat\Mink\Mink; use Behat\Mink\Session; use FriendsOfBehat\SymfonyExtension\Mink\MinkParameters; +use FriendsOfBehat\SymfonyExtension\ServiceContainer\SymfonyExtension; use Symfony\Component\BrowserKit\Client; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -15,6 +16,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\HttpKernel\KernelInterface; final class FriendsOfBehatSymfonyExtensionExtension extends Extension implements CompilerPassInterface { @@ -22,6 +25,7 @@ final class FriendsOfBehatSymfonyExtensionExtension extends Extension implements { $this->provideMinkIntegration($container); $this->registerBehatContainer($container); + $this->registerDriverBehatContainer($container); $container->registerForAutoconfiguration(Context::class)->addTag('fob.context'); } @@ -47,6 +51,27 @@ final class FriendsOfBehatSymfonyExtensionExtension extends Extension implements $container->setDefinition('behat.service_container', $behatServiceContainerDefinition); } + private function registerDriverBehatContainer(ContainerBuilder $container): void + { + $driverKernelDefinition = new Definition(KernelInterface::class, [SymfonyExtension::DRIVER_KERNEL_ID]); + $driverKernelDefinition->setFactory([new Reference('behat.service_container'), 'get']); + $driverKernelDefinition->setPublic(true); + $driverKernelDefinition->setLazy(true); + + $driverServiceContainerDefinition = new Definition(ContainerInterface::class); + $driverServiceContainerDefinition->setFactory([$driverKernelDefinition, 'getContainer']); + $driverServiceContainerDefinition->setPublic(true); + $driverServiceContainerDefinition->setLazy(true); + + $driverTestServiceContainerDefinition = new Definition(ContainerInterface::class, ['test.service_container']); + $driverTestServiceContainerDefinition->setFactory([$driverServiceContainerDefinition, 'get']); + $driverTestServiceContainerDefinition->setPublic(true); + $driverTestServiceContainerDefinition->setLazy(true); + + $container->setDefinition('behat.driver.service_container', $driverTestServiceContainerDefinition); + $container->registerAliasForArgument('behat.driver.service_container', ContainerInterface::class, 'driver container'); + } + private function provideBrowserKitIntegration(ContainerBuilder $container): void { if (!class_exists(Client::class) || !$container->has('test.client')) { diff --git a/src/ServiceContainer/SymfonyExtension.php b/src/ServiceContainer/SymfonyExtension.php index f0d920c..d8e0565 100644 --- a/src/ServiceContainer/SymfonyExtension.php +++ b/src/ServiceContainer/SymfonyExtension.php @@ -34,7 +34,7 @@ final class SymfonyExtension implements Extension * Kernel used by Symfony driver to isolate web container from contexts' container. * Container is rebuilt before every request. */ - private const DRIVER_KERNEL_ID = 'fob_symfony.driver_kernel'; + public const DRIVER_KERNEL_ID = 'fob_symfony.driver_kernel'; /** @var bool */ private $minkExtensionFound = false;