This course is still being released! Check back later for more chapters.

Get Notified About this Course!

We will send you messages regarding this course only
and nothing else, we promise.
You can unsubscribe anytime by emailing us at:
privacy@symfonycasts.com
Login to bookmark this video
Buy Access to Course
30.

Pruebas de Doctrine

|

Share this awesome video!

|

Keep on Learning!

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Es hora de convertir este stub de prueba de integración en una prueba adecuada para nuestro bundle. ¡Vamos a utilizar una base de datos real y entidades reales para ello!

En el terminal, instala Zenstruck Foundry para que nos ayude a gestionar nuestra base de datos de pruebas y nuestras entidades:

symfony composer require --dev zenstruck/foundry

Entidades de prueba

De vuelta a nuestro IDE, en el directorio tutorial, copia la carpeta Entity en el directorio tests/Fixture de nuestro bundle. Si no ves estas entidades, cópialas desde el script que aparece a continuación:

// ... lines 1 - 2
namespace SymfonyCasts\ObjectTranslationBundle\Tests\Fixture\Entity;
use Doctrine\ORM\Mapping as ORM;
use SymfonyCasts\ObjectTranslationBundle\Mapping\Translatable;
use SymfonyCasts\ObjectTranslationBundle\Mapping\TranslatableProperty;
#[Translatable('entity1')]
#[ORM\Entity]
class Entity1
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
public int $id;
#[ORM\Column]
#[TranslatableProperty]
public string $property1;
}

// ... lines 1 - 2
namespace SymfonyCasts\ObjectTranslationBundle\Tests\Fixture\Entity;
use Doctrine\ORM\Mapping as ORM;
use SymfonyCasts\ObjectTranslationBundle\Model\Translation as BaseTranslation;
#[ORM\Entity]
class Translation extends BaseTranslation
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
public int $id;
}

Entity1 es nuestra entidad simulada que traduciremos en nuestras pruebas. Es traducible, tiene un ID y una propiedad traducible.

La entidad Translation es igual que la de nuestra aplicación.

Más configuración de TestKernel

En nuestro TestKernel, tenemos que decirle qué bundles cargar. Anula el método registerBundles(). Dentro, yield new FrameworkBundle(),yield new DoctrineBundle(), yield new ZenstruckFoundryBundle(), y finalmente, nuestro bundle, yield new ObjectTranslationBundle():

// ... lines 1 - 15
class TestKernel extends Kernel
{
// ... lines 18 - 19
public function registerBundles(): iterable
{
yield new FrameworkBundle();
yield new DoctrineBundle();
yield new ZenstruckFoundryBundle();
yield new ObjectTranslationBundle();
}
// ... lines 27 - 51
}

Ahora necesitamos más configuración. En configureContainer(), añade$builder->loadFromExtension('symfonycasts_object_translation', ['translation_class' => Translation::class]). Es difícil de ver en esta pequeña pantalla, pero necesitamos importar el de nuestras instalaciones de prueba. Creo que es ésta. Me desplazaré hasta los espacios de nombres para confirmarlo. Sí, es éste:

// ... lines 1 - 15
class TestKernel extends Kernel
{
// ... lines 18 - 27
private function configureContainer(ContainerConfigurator $container, LoaderInterface $loader, ContainerBuilder $builder): void
{
// ... lines 30 - 33
$container->extension('symfonycasts_object_translation', [
'translation_class' => Translation::class,
]);
// ... lines 37 - 50
}
}

Ahora a configurar Doctrine. Añade$builder->loadFromExtension('doctrine', []). Primero configura dbal con'url' => 'sqlite:///%kernel.project_dir%/var/data.db':

// ... lines 1 - 15
class TestKernel extends Kernel
{
// ... lines 18 - 27
private function configureContainer(ContainerConfigurator $container, LoaderInterface $loader, ContainerBuilder $builder): void
{
// ... lines 30 - 37
$container->extension('doctrine', [
'dbal' => [
'url' => 'sqlite:///%kernel.project_dir%/var/data.db',
],
// ... lines 42 - 49
]);
}
}

Para la configuración de orm, voy a pegar este fragmento (puedes cogerlo del script de abajo):

// ... lines 1 - 15
class TestKernel extends Kernel
{
// ... lines 18 - 27
private function configureContainer(ContainerConfigurator $container, LoaderInterface $loader, ContainerBuilder $builder): void
{
// ... lines 30 - 37
$container->extension('doctrine', [
// ... lines 39 - 41
'orm' => [
'mappings' => [
'Test' => [
'dir' => '%kernel.project_dir%/tests/Fixture/Entity',
'prefix' => 'SymfonyCasts\ObjectTranslationBundle\Tests\Fixture\Entity',
]
]
],
]);
}
}

Esto indica al ORM de Doctrine dónde encontrar nuestras entidades de prueba.

La prueba ObjectTransator::translate()

De vuelta a nuestra clase de prueba, borra el método de prueba existente. En primer lugar, tenemos que crear una instancia de nuestra entidad simulada, Entity1. Para ello utilizaremos una fábrica de Foundry. Podríamos crear una clase de fábrica real, pero para simplificar las cosas, utilizaremos una fábrica dinámica. Escribe $entity = persist(), importa la función de Foundry Entity1::class como primer argumento, y un array con 'property1' => 'value1' como segundo:

// ... lines 1 - 12
class ObjectTranslatorTest extends KernelTestCase
// ... lines 14 - 16
public function testCanAccessService()
{
$entity = persist(Entity1::class, [
'property1' => 'value1',
]);
// ... lines 22 - 33
}
}

Ahora la entidad Translation: persist(Translation::class). De nuevo, asegúrate de importar la de nuestras instalaciones de prueba. El array será 'objectType' => '', pasa a nuestra clase Entity1 para confirmar el alias: entity1. A continuación, 'objectId' => $entity->id,'locale' => 'fr', 'field' => 'property1', y por último, 'value' => 'translated1':

// ... lines 1 - 12
class ObjectTranslatorTest extends KernelTestCase
// ... lines 14 - 16
public function testCanAccessService()
{
// ... lines 19 - 21
persist(Translation::class, [
'objectType' => 'entity1',
'objectId' => $entity->id,
'locale' => 'fr',
'field' => 'property1',
'value' => 'translated1',
]);
// ... lines 29 - 33
}
}

Más abajo, obtén nuestro servicio traductor de objetos con$translator = self::getContainer()->get(ObjectTranslator::class):

// ... lines 1 - 12
class ObjectTranslatorTest extends KernelTestCase
// ... lines 14 - 16
public function testCanAccessService()
{
// ... lines 19 - 29
$translator = self::getContainer()->get(ObjectTranslator::class);
// ... lines 31 - 33
}
}

Traduce la entidad:$translated = $translator->translate($entity) y pasa fr como segundo argumento para forzar la traducción al francés:

// ... lines 1 - 12
class ObjectTranslatorTest extends KernelTestCase
// ... lines 14 - 16
public function testCanAccessService()
{
// ... lines 19 - 30
$translated = $translator->translate($entity, 'fr');
// ... lines 32 - 33
}
}

Por último, afirma que la propiedad traducida es la que esperamos:$this->assertSame('translated1', $translated->property1);:

// ... lines 1 - 12
class ObjectTranslatorTest extends KernelTestCase
// ... lines 14 - 16
public function testCanAccessService()
{
// ... lines 19 - 32
$this->assertSame('translated1', $translated->property1);
}
}

¡Momento de la verdad! De vuelta al terminal, ejecuta nuestras pruebas:

symfony php vendor/bin/phpunit

¡Maldita sea! Un error: "Foundry aún no se ha iniciado"

Ohhh, olvidé los rasgos necesarios de Foundry. De vuelta a la clase de prueba,use Factories, que inicializa Foundry, y ResetDatabase, que reinicia la base de datos antes de cada prueba:

// ... lines 1 - 12
class ObjectTranslatorTest extends KernelTestCase
{
use Factories, ResetDatabase;
// ... lines 16 - 34
}

Momento de la verdad, toma dos:

symfony php vendor/bin/phpunit

¡Genial! ¡Todo verde! ¡Nuestra prueba de integración con una base de datos real funciona!

A continuación, probaremos nuestro bundle con diferentes versiones de Symfony para garantizar la compatibilidad.