Nuevo en Symfony 4.1: Simplificado el uso de servicios en tests
En Symfony 3.4 hicimos que todos los servicios fueran privados por defecto,
de manera que ya no puedes realizar llamadas como $this->get('mi_servicio')
dentro de un controlador para obtener un servicio.
Tomamos esta decisión porque usar el contenedor de servicios directamente no es una buena práctica que queramos promover. El principal motivo es que oculta las dependencias de tus clases, haciendo que estén más acopladas y dificultando los tests.
Siempre que eliminamos una funcionalidad como esta, intentamos ofrecer una alternativa que sea mejor y en lo posible, tan fácil o más de usar que la anterior. Por eso ahora en los controladores puedes inyectar servicios en los argumentos de sus acciones y constructores.
El único problema que quedaba es que los tests ahora eran más complicados que
antes. De hecho, algunos programadores/as definían una configuración en el
entorno test
para hacer todos los servicios públicos en los tests. En Symfony
4.1 hemos decidido aplicar la misma idea y podrás por defecto
acceder a los servicios privados dentro de los tests.
En la práctica, los tests basados en WebTestCase
y KernelTestCase
ahora
pueden acceder a un contenedor especial mediante la propiedad
static::$container
que permite acceder a los servicios privados:
use App\Entity\User; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Console\Tester\CommandTester; class AddUserCommandTest extends WebTestCase { private function assertUserCreated() { self::bootKernel(); // este es el contendor original sin ningún cambio $container = self::$kernel->getContainer(); // este es el contenedor especial que permite acceder a servicios privados $client = self::createClient(); $user = self::$container->get('doctrine')->getRepository(User::class)->findOneByEmail('...'); $this->assertTrue(self::$container->get('security.password_encoder')->isPasswordValid($user, '...'); // ... }
Algo a tener en cuenta es que, debido a cómo funciona el contenedor de sevicios
de Symfony, lo servicios que no se usan se eliminan del contenedor. Esto
significa que si tienes un servicio privado que no se usa en ningún otro
servicio, Symfony lo eliminará y no podrás acceder a el tal y como se explica en
este artículo. La solución es definit el servicio como public
explícitamente
para que Symfony no lo elimine.
Esta funcionalidad fue contribuida por Nicolas Grekas en el pull request #26499.
Fuente: New in Symfony 4.1: Simpler service testing
Comentarios
Proyectos Symfony destacados
La forma más sencilla de generar el backend de tus aplicaciones Symfony. Ver más
Síguenos en @symfony_es para acceder a las últimas noticias.