If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeBob nos acaba de decir que necesita mostrar qué dinos están aceptando comida en nuestra aplicación... Quiero decir que aceptan visitas. GenLab tiene unos protocolos estrictos: los visitantes del parque pueden visitar a los dinos sanos... pero si están enfermos, no se admiten visitas. Para ayudar a mostrar esto, necesitamos almacenar el estado de salud de cada dino y tener una forma fácil de averiguar si esto significa que aceptan visitas o no...
Empecemos por añadir un método - isAcceptingVisitors()
a Dinosaur
. Pero, lo haremos a la manera de TDD escribiendo primero el test. En DinosaurTest
añadepublic function testIsAcceptingVisitorsByDefault()
. Dentro, $dino = new Dinosaur()
y llamémosle Dennis
.
Si simplemente instanciamos un Dinosaur
y no hacemos nada más, la política de GenLab establece que está bien visitar ese Dinosaurio. Así que assertTrue()
que DennisisAcceptingVisitors()
.
Debajo de esta prueba, añade otra llamada testIsNotAcceptingVisitorsIfSick()
. Y por ahora, seamos perezosos y digamos simplemente $this->markTestIncomplete()
.
Bien, probemos las pruebas:
./vendor/bin/phpunit --testdox
Y... ¡no hay sorpresa! Nuestra primera prueba nueva falla:
Llamada a un método indefinido.
Pero nuestra siguiente prueba tiene este extraño círculo ∅
porque hemos marcado la prueba como incompleta. A veces utilizo esto cuando sé que tengo que escribir una prueba... pero aún no estoy preparado para hacerlo. PHPUnit también tiene un método markSkipped()
que puede utilizarse para omitir pruebas bajo ciertas condiciones, como si una prueba debe ejecutarse en PHP 8.1.
En cualquier caso, volvamos a la codificación... En nuestra clase Dinosaur
, añadimos un métodoisAcceptingVisitors()
que devuelve un bool
, y dentro devolveremos true
.
Veamos qué ocurre ahora al ejecutar nuestras pruebas...
./vendor/bin/phpunit --testdox
Y... Sí! Is accepting visitors by default
... ¡ahora pasa! Todavía tenemos una prueba incompleta como recordatorio, pero no está provocando que todo nuestro conjunto de pruebas falle.
Terminemos ahora. Si echamos un vistazo a las cuestiones en GitHub, GenLab está utilizando etiquetas para identificar la "salud" de cada dino: "Enfermo" frente a "Sano". Muy pronto, vamos a leer estas etiquetas y a utilizarlas en nuestra aplicación. Para prepararnos para ello, necesitamos una forma de almacenar la salud actual de cada Dinosaur
.
Dentro de la prueba, elimina markAsIncomplete()
y crea un $dino
llamadoBumpy
... es un triceratops. Ahora llama a $dino->setHealth('Sick')
y luego a assertFalse()
que es un Bumpy isAcceptingVisitors()
. Está malhumorado cuando está enfermo.
Pero, no nos sorprende, PHPStorm nos dice
Método setHealth() no encontrado dentro de Dinosaurio
Así que... dejemos de ejecutar la prueba y vayamos directamente a Dinosaur
para añadir un método setHealth()
que acepte un argumento string $health
... y devuelva void
. Dentro, digamos $this->health = $health
... y luego arriba, añade una propiedad private string $health
que por defecto sea Healthy
.
¡Genial! Ahora sólo tenemos que actualizar isAcceptingVisitors()
para que devuelva$this->health === $healthy
en lugar de true
.
Cruza los dedos para que nuestras pruebas pasen ahora...
./vendor/bin/phpunit --testdox
Y... ¡Misión cumplida!
Ahora que las pruebas están pasando, estoy pensando que deberíamos refactorizar el método setHealth()
para que sólo permitaSick
o Healthy
... y no algo como Dancing
... Dentro de src/
, crea un nuevo directorio Enum/
y luego una nueva clase: HealthStatus
. Para la plantilla, selecciona Enum
y haz clic en OK
. Necesitamos que HealthStatus
esté respaldado por un : string
... Y nuestro primer case HEALTHY
devolverá Healthy
, luego case SICK
devolveráSick
.
En la propiedad Dinosaur::$health
, por defecto, HealthStatus::HEALTHY
. Y cambia el tipo de propiedad a HealthStatus
. Abajo en isAcceptingVisitors()
, devuelve true si $this->health === HealthStatus::HEALTHY
. Abajo en setHealth()
, cambia el tipo de argumento de string
a HealthStatus
.
Lo último que hay que hacer es utilizar HealthStatus::SICK
en nuestra prueba.
¡A ver si rompemos algo!
./vendor/bin/phpunit --testdox
Y... ¡Ya! No hemos roto nada... Sólo estoy un poco sorprendido.
Para cumplir los deseos de Bob, abre la plantilla main/index.html.twig
y añade un título Accepting Visitors
a la tabla. En el bucle dino, crea un nuevo <td>
y llama a dino.acceptingVisitors
. MostraremosYes
si es verdadero o No
si obtenemos falso.
En el navegador, actualiza la página de estado... Y... ¡WooHoo! Todos nuestros dinos están aceptando visitas... ¡porque no hemos puesto ninguno como "enfermo" en nuestro código!
Pero... Ya sabemos, por haber mirado antes en GitHub, que algunos de nuestros dinos están enfermos. Lo siguiente: vamos a utilizar la API de GitHub para leer las etiquetas de nuestro repositorio de GitHub y establecer la salud real de cada Dinosaur
para que nuestro panel se actualice en tiempo real.
"Houston: no signs of life"
Start the conversation!
// composer.json
{
"require": {
"php": ">=8.1.0",
"ext-ctype": "*",
"ext-iconv": "*",
"symfony/asset": "6.1.*", // v6.1.0
"symfony/console": "6.1.*", // v6.1.4
"symfony/dotenv": "6.1.*", // v6.1.0
"symfony/flex": "^2", // v2.2.3
"symfony/framework-bundle": "6.1.*", // v6.1.4
"symfony/http-client": "6.1.*", // v6.1.4
"symfony/runtime": "6.1.*", // v6.1.3
"symfony/twig-bundle": "6.1.*", // v6.1.1
"symfony/yaml": "6.1.*" // v6.1.4
},
"require-dev": {
"phpunit/phpunit": "^9.5", // 9.5.23
"symfony/browser-kit": "6.1.*", // v6.1.3
"symfony/css-selector": "6.1.*", // v6.1.3
"symfony/phpunit-bridge": "^6.1" // v6.1.3
}
}