Skip to content

[FrameworkBundle] Add KernelTestCase::getContainer() #40366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions UPGRADE-5.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ FrameworkBundle
* Deprecate the `session.storage` alias and `session.storage.*` services, use the `session.storage.factory` alias and `session.storage.factory.*` services instead
* Deprecate the `framework.session.storage_id` configuration option, use the `framework.session.storage_factory_id` configuration option instead
* Deprecate the `session` service and the `SessionInterface` alias, use the `\Symfony\Component\HttpFoundation\Request::getSession()` or the new `\Symfony\Component\HttpFoundation\RequestStack::getSession()` methods instead
* Deprecate the `KernelTestCase::$container` property, use `KernelTestCase::getContainer()` instead

HttpFoundation
--------------
Expand Down
1 change: 1 addition & 0 deletions UPGRADE-6.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ FrameworkBundle
* The `form.factory`, `form.type.file`, `translator`, `security.csrf.token_manager`, `serializer`,
`cache_clearer`, `filesystem` and `validator` services are now private.
* Removed the `lock.RESOURCE_NAME` and `lock.RESOURCE_NAME.store` services and the `lock`, `LockInterface`, `lock.store` and `PersistingStoreInterface` aliases, use `lock.RESOURCE_NAME.factory`, `lock.factory` or `LockFactory` instead.
* Remove the `KernelTestCase::$container` property, use `KernelTestCase::getContainer()` instead

HttpFoundation
--------------
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ CHANGELOG
* Add tag `assets.package` to register asset packages
* Add support to use a PSR-6 compatible cache for Doctrine annotations
* Deprecate all other values than "none", "php_array" and "file" for `framework.annotation.cache`
* Add `KernelTestCase::getContainer()` as the best way to get a container in tests

5.2.0
-----
Expand Down
24 changes: 24 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Contracts\Service\ResetInterface;

Expand All @@ -34,6 +35,8 @@ abstract class KernelTestCase extends TestCase

/**
* @var ContainerInterface
*
* @deprecated since Symfony 5.3, use static::getContainer() instead
*/
protected static $container;

Expand Down Expand Up @@ -86,6 +89,27 @@ protected static function bootKernel(array $options = [])
return static::$kernel;
}

/**
* Provides a dedicated test container with access to both public and private
* services. The container will not include private services that has been
* inlined or removed. Private services will be removed when they are not
* used by other services.
*
* Using this method is the best way to get a container from your test code.
*/
protected static function getContainer(): ContainerInterface
{
if (!static::$booted) {
static::bootKernel();
}

try {
return self::$kernelContainer->get('test.service_container');
} catch (ServiceNotFoundException $e) {
throw new \LogicException('Could not find service "test.service_container". Try updating the "framework.test" config to "true".', 0, $e);
}
}

/**
* Creates a Kernel.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,13 @@ public static function getMailerMessage(int $index = 0, string $transport = null

private static function getMessageMailerEvents(): MessageEvents
{
if (self::$container->has('mailer.message_logger_listener')) {
return self::$container->get('mailer.message_logger_listener')->getEvents();
$container = static::getContainer();
if ($container->has('mailer.message_logger_listener')) {
return $container->get('mailer.message_logger_listener')->getEvents();
}

if (self::$container->has('mailer.logger_message_listener')) {
return self::$container->get('mailer.logger_message_listener')->getEvents();
if ($container->has('mailer.logger_message_listener')) {
return $container->get('mailer.logger_message_listener')->getEvents();
}

static::fail('A client must have Mailer enabled to make email assertions. Did you forget to require symfony/mailer?');
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Test/TestContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
use Symfony\Component\HttpKernel\KernelInterface;

/**
* A special container used in tests. This gives access to both public and
* private services. The container will not include private services that has
* been inlined or removed. Private services will be removed when they are not
* used by other services.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,36 @@ public function testAnnotationReaderAutowiring()
{
static::bootKernel(['root_config' => 'no_annotations_cache.yml', 'environment' => 'no_annotations_cache']);

$annotationReader = static::$container->get('test.autowiring_types.autowired_services')->getAnnotationReader();
$annotationReader = self::getContainer()->get('test.autowiring_types.autowired_services')->getAnnotationReader();
$this->assertInstanceOf(AnnotationReader::class, $annotationReader);
}

public function testCachedAnnotationReaderAutowiring()
{
static::bootKernel();

$annotationReader = static::$container->get('test.autowiring_types.autowired_services')->getAnnotationReader();
$annotationReader = self::getContainer()->get('test.autowiring_types.autowired_services')->getAnnotationReader();
$this->assertInstanceOf(class_exists(PsrCachedReader::class) ? PsrCachedReader::class : CachedReader::class, $annotationReader);
}

public function testEventDispatcherAutowiring()
{
static::bootKernel(['debug' => false]);

$autowiredServices = static::$container->get('test.autowiring_types.autowired_services');
$autowiredServices = self::getContainer()->get('test.autowiring_types.autowired_services');
$this->assertInstanceOf(EventDispatcher::class, $autowiredServices->getDispatcher(), 'The event_dispatcher service should be injected if the debug is not enabled');

static::bootKernel(['debug' => true]);

$autowiredServices = static::$container->get('test.autowiring_types.autowired_services');
$autowiredServices = self::getContainer()->get('test.autowiring_types.autowired_services');
$this->assertInstanceOf(TraceableEventDispatcher::class, $autowiredServices->getDispatcher(), 'The debug.event_dispatcher service should be injected if the debug is enabled');
}

public function testCacheAutowiring()
{
static::bootKernel();

$autowiredServices = static::$container->get('test.autowiring_types.autowired_services');
$autowiredServices = self::getContainer()->get('test.autowiring_types.autowired_services');
$this->assertInstanceOf(FilesystemAdapter::class, $autowiredServices->getCachePool());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public function testBundlePublicDir()
public function testBundleTwigTemplatesDir()
{
static::bootKernel(['test_case' => 'BundlePaths']);
$twig = static::$container->get('twig.alias');
$bundlesMetadata = static::$container->getParameter('kernel.bundles_metadata');
$twig = static::getContainer()->get('twig.alias');
$bundlesMetadata = static::getContainer()->getParameter('kernel.bundles_metadata');

$this->assertSame([$bundlesMetadata['LegacyBundle']['path'].'/Resources/views'], $twig->getLoader()->getPaths('Legacy'));
$this->assertSame("OK\n", $twig->render('@Legacy/index.html.twig'));
Expand All @@ -53,7 +53,7 @@ public function testBundleTwigTemplatesDir()
public function testBundleTranslationsDir()
{
static::bootKernel(['test_case' => 'BundlePaths']);
$translator = static::$container->get('translator.alias');
$translator = static::getContainer()->get('translator.alias');

$this->assertSame('OK', $translator->trans('ok_label', [], 'legacy'));
$this->assertSame('OK', $translator->trans('ok_label', [], 'modern'));
Expand All @@ -62,7 +62,7 @@ public function testBundleTranslationsDir()
public function testBundleValidationConfigDir()
{
static::bootKernel(['test_case' => 'BundlePaths']);
$validator = static::$container->get('validator.alias');
$validator = static::getContainer()->get('validator.alias');

$this->assertTrue($validator->hasMetadataFor(LegacyPerson::class));
$this->assertCount(1, $constraintViolationList = $validator->validate(new LegacyPerson('john', 5)));
Expand All @@ -76,7 +76,7 @@ public function testBundleValidationConfigDir()
public function testBundleSerializationConfigDir()
{
static::bootKernel(['test_case' => 'BundlePaths']);
$serializer = static::$container->get('serializer.alias');
$serializer = static::getContainer()->get('serializer.alias');

$this->assertEquals(['full_name' => 'john', 'age' => 5], $serializer->normalize(new LegacyPerson('john', 5), 'json'));
$this->assertEquals(['full_name' => 'john', 'age' => 5], $serializer->normalize(new ModernPerson('john', 5), 'json'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function testClearFailed()
{
$tester = $this->createCommandTester();
/** @var FilesystemAdapter $pool */
$pool = static::$container->get('cache.public_pool');
$pool = static::getContainer()->get('cache.public_pool');
$item = $pool->getItem('foo');
$item->set('baz');
$pool->save($item);
Expand Down Expand Up @@ -108,7 +108,7 @@ public function testClearFailed()
private function createCommandTester()
{
$application = new Application(static::$kernel);
$application->add(new CachePoolClearCommand(static::$container->get('cache.global_clearer')));
$application->add(new CachePoolClearCommand(static::getContainer()->get('cache.global_clearer')));

return new CommandTester($application->find('cache:pool:clear'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function testRedisCustomCachePools()
private function doTestCachePools($options, $adapterClass)
{
static::bootKernel($options);
$container = static::$container;
$container = static::getContainer();

$pool1 = $container->get('cache.pool1');
$this->assertInstanceOf($adapterClass, $pool1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public function testDumpContainerIfNotExists()
$application = new Application(static::$kernel);
$application->setAutoExit(false);

@unlink(static::$container->getParameter('debug.container.dump'));
@unlink(static::getContainer()->getParameter('debug.container.dump'));

$tester = new ApplicationTester($application);
$tester->run(['command' => 'debug:container']);

$this->assertFileExists(static::$container->getParameter('debug.container.dump'));
$this->assertFileExists(static::getContainer()->getParameter('debug.container.dump'));
}

public function testNoDebug()
Expand Down Expand Up @@ -91,7 +91,7 @@ public function testDescribeEnvVars()
$application = new Application(static::$kernel);
$application->setAutoExit(false);

@unlink(static::$container->getParameter('debug.container.dump'));
@unlink(static::getContainer()->getParameter('debug.container.dump'));

$tester = new ApplicationTester($application);
$tester->run(['command' => 'debug:container', '--env-vars' => true], ['decorated' => false]);
Expand Down Expand Up @@ -128,7 +128,7 @@ public function testDescribeEnvVar()
$application = new Application(static::$kernel);
$application->setAutoExit(false);

@unlink(static::$container->getParameter('debug.container.dump'));
@unlink(static::getContainer()->getParameter('debug.container.dump'));

$tester = new ApplicationTester($application);
$tester->run(['command' => 'debug:container', '--env-var' => 'js'], ['decorated' => false]);
Expand Down Expand Up @@ -156,7 +156,7 @@ public function testGetDeprecation()
$application = new Application(static::$kernel);
$application->setAutoExit(false);

@unlink(static::$container->getParameter('debug.container.dump'));
@unlink(static::getContainer()->getParameter('debug.container.dump'));

$tester = new ApplicationTester($application);
$tester->run(['command' => 'debug:container', '--deprecations' => true]);
Expand All @@ -176,7 +176,7 @@ public function testGetDeprecationNone()
$application = new Application(static::$kernel);
$application->setAutoExit(false);

@unlink(static::$container->getParameter('debug.container.dump'));
@unlink(static::getContainer()->getParameter('debug.container.dump'));

$tester = new ApplicationTester($application);
$tester->run(['command' => 'debug:container', '--deprecations' => true]);
Expand All @@ -194,7 +194,7 @@ public function testGetDeprecationNoFile()
$application = new Application(static::$kernel);
$application->setAutoExit(false);

@unlink(static::$container->getParameter('debug.container.dump'));
@unlink(static::getContainer()->getParameter('debug.container.dump'));

$tester = new ApplicationTester($application);
$tester->run(['command' => 'debug:container', '--deprecations' => true]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ public function testContainerCompilationInDebug()
{
$this->createClient(['test_case' => 'ContainerDump', 'root_config' => 'config.yml']);

$this->assertTrue(static::$container->has('serializer'));
$this->assertTrue(static::getContainer()->has('serializer'));
}

public function testContainerCompilation()
{
$this->createClient(['test_case' => 'ContainerDump', 'root_config' => 'config.yml', 'debug' => false]);

$this->assertTrue(static::$container->has('serializer'));
$this->assertTrue(static::getContainer()->has('serializer'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;

use Symfony\Bundle\FrameworkBundle\Test\TestContainer;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\NonPublicService;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PrivateService;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PublicService;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\UnusedPrivateService;
use Symfony\Component\DependencyInjection\ContainerInterface;

class KernelTestCaseTest extends AbstractWebTestCase
{
public function testThatPrivateServicesAreUnavailableIfTestConfigIsDisabled()
{
static::bootKernel(['test_case' => 'TestServiceContainer', 'root_config' => 'test_disabled.yml', 'environment' => 'test_disabled']);

$this->expectException(\LogicException::class);
static::getContainer();
}

public function testThatPrivateServicesAreAvailableIfTestConfigIsEnabled()
{
static::bootKernel(['test_case' => 'TestServiceContainer']);

$container = static::getContainer();
$this->assertInstanceOf(ContainerInterface::class, $container);
$this->assertInstanceOf(TestContainer::class, $container);
$this->assertTrue($container->has(PublicService::class));
$this->assertTrue($container->has(NonPublicService::class));
$this->assertTrue($container->has(PrivateService::class));
$this->assertTrue($container->has('private_service'));
$this->assertFalse($container->has(UnusedPrivateService::class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public function testEnvelopeListener()
$this->assertEquals('sender@example.org', $envelope->getSender()->getAddress());
};

$eventDispatcher = self::$container->get(EventDispatcherInterface::class);
$logger = self::$container->get('logger');
$eventDispatcher = self::getContainer()->get(EventDispatcherInterface::class);
$logger = self::getContainer()->get('logger');

$testTransport = new class($eventDispatcher, $logger, $onDoSend) extends AbstractTransport {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function testPhpDocPriority()
{
static::bootKernel(['test_case' => 'Serializer']);

$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_INT))], static::$container->get('property_info')->getTypes('Symfony\Bundle\FrameworkBundle\Tests\Functional\Dummy', 'codes'));
$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_INT))], static::getContainer()->get('property_info')->getTypes('Symfony\Bundle\FrameworkBundle\Tests\Functional\Dummy', 'codes'));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testDeserializeArrayOfObject()
{
static::bootKernel(['test_case' => 'Serializer']);

$result = static::$container->get('serializer.alias')->deserialize('{"bars": [{"id": 1}, {"id": 2}]}', Foo::class, 'json');
$result = static::getContainer()->get('serializer.alias')->deserialize('{"bars": [{"id": 1}, {"id": 2}]}', Foo::class, 'json');

$bar1 = new Bar();
$bar1->id = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

class TestServiceContainerTest extends AbstractWebTestCase
{
/**
* @group legacy
*/
public function testThatPrivateServicesAreUnavailableIfTestConfigIsDisabled()
{
static::bootKernel(['test_case' => 'TestServiceContainer', 'root_config' => 'test_disabled.yml', 'environment' => 'test_disabled']);
Expand All @@ -33,6 +36,9 @@ public function testThatPrivateServicesAreUnavailableIfTestConfigIsDisabled()
$this->assertFalse(static::$container->has(UnusedPrivateService::class));
}

/**
* @group legacy
*/
public function testThatPrivateServicesAreAvailableIfTestConfigIsEnabled()
{
static::bootKernel(['test_case' => 'TestServiceContainer']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public function testAccessDecisionManagerAutowiring()
{
static::bootKernel(['debug' => false]);

$autowiredServices = static::$container->get('test.autowiring_types.autowired_services');
$autowiredServices = static::getContainer()->get('test.autowiring_types.autowired_services');
$this->assertInstanceOf(AccessDecisionManager::class, $autowiredServices->getAccessDecisionManager(), 'The security.access.decision_manager service should be injected in debug mode');

static::bootKernel(['debug' => true]);

$autowiredServices = static::$container->get('test.autowiring_types.autowired_services');
$autowiredServices = static::getContainer()->get('test.autowiring_types.autowired_services');
$this->assertInstanceOf(TraceableAccessDecisionManager::class, $autowiredServices->getAccessDecisionManager(), 'The debug.security.access.decision_manager service should be injected in non-debug mode');
}

Expand Down
Loading