diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1b494..9b033b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://git.d3data.de/D3Public/TestingTools/compare/1.0.0.0...rel_1.x) +- can modify DI container services in runtime ## [1.0.0.0](https://git.d3data.de/D3Public/TestingTools/releases/tag/1.0.0.0) - 2022-11-11 ### Added diff --git a/src/Development/CanAccessRestricted.php b/src/Development/CanAccessRestricted.php index c879816..42462c8 100644 --- a/src/Development/CanAccessRestricted.php +++ b/src/Development/CanAccessRestricted.php @@ -17,6 +17,8 @@ declare(strict_types=1); namespace D3\TestingTools\Development; +use OxidEsales\EshopCommunity\Internal\Container\ContainerBuilderFactory; +use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; use PHPUnit\Framework\MockObject\MockObject; use ReflectionClass; use ReflectionException; @@ -109,4 +111,40 @@ trait CanAccessRestricted $property->setAccessible(true); return $property->getValue($object); } + + /** + * use \OxidEsales\EshopCommunity\Internal\Container\ContainerFactory::resetContainer() to undo these modifications + * @param array $services + * @return void + * @throws ReflectionException + */ + public function addServiceMocks(array $services): void + { + $builder = (new ContainerBuilderFactory())->create()->getContainer(); + + array_walk($services, function ($service, $serviceId) use ($builder) { + if ($builder->has($serviceId)) { + $builder->set($serviceId, $service); + } + }); + + $builder->compile(); + $container = ContainerFactory::getInstance(); + $reflection = new ReflectionClass($container); + $property = $reflection->getProperty($this->getDIContainerPropertyName($reflection)); + $property->setValue($container, $builder); + } + + protected function getDIContainerPropertyName(ReflectionClass $containerReflection): string + { + $property = current(array_filter($containerReflection->getProperties(), function (ReflectionProperty $property) { + return stristr($property->getName(), 'container'); + })); + + if (!is_object($property) || !$property instanceof ReflectionProperty) { + throw new \RuntimeException("can't find container property"); + } + + return $property->getName(); + } }