Norway



Nicolas Grekas  - 6baa34bc1e5c347b1003f6abe8691de1 s 100 - Simpler service testing (Symfony Blog)

In 3.4 we made all services private by default meaning that you
cannot longer call $this->get('my__id') in your controllers to
quickly get some service.

We made this change because using the service container directly is not
considered a good practice: it hides the dependencies of your classes, making
them coupled to external configuration, thus harder to test and to review.

Whenever we remove a feature like that, we provide an alternative that is
considered better and, if possible, as simple to use as the previous one. That’s
why controllers allow injecting services with type hints in their action methods
and their constructors.

The only remaining drawback of “private services by default” is that was
harder than before. Some developers even defined some config in the test
environment to make all services public in tests. In Symfony 4.1, we did the
same and now tests allow fetching private services by default.

In practice, tests based on WebTestCase and KernelTestCase now access
to a special container via $client->getContainer() or the
static::$container property that allows to fetch non-removed private services:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

13
14
15
16
17
18
19
20
21
22
23
use AppEntityUser;
use SymfonyBundleFrameworkBundleTestKernelTestCase;
use SymfonyComponentConsoleTesterCommandTester;

class AddUserCommandTest extends KernelTestCase
{
    private function assertUserCreated()
    {
        self::bootKernel();

        // returns the real and unchanged service container
        $container = self::$kernel->getContainer();

        // returns the special container that allows fetching private services
        $client = static::createClient();
        $container = $client->getContainer();
        // alternative way to get the special container:
        // $container = self::$container;

        $user = self::$container->get('doctrine')->getRepository(User::class)->findOneByEmail('...');
        $this->assertTrue(self::$container->get('.password_encoder')->isPasswordValid($user, '...');
        // ...
}



Source link

LEAVE A REPLY

Please enter your comment!
Please enter your name here