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 SubscribeHagamos realidad esta prueba con datos y aserciones.
Hay dos formas principales de hacer aserciones con Browser. En primer lugar, viene con un montón de métodos incorporados para ayudarte, como ->assertJson()
. O... siempre puedes coger el JSON que vuelve de una ruta y comprobar las cosas utilizando las aserciones incorporadas de PHPUnit que conoces y adoras. Veremos ambas cosas.
Empecemos comprobando ->assertJson()
:
... lines 1 - 8 | |
class DragonTreasureResourceTest extends KernelTestCase | |
{ | |
... lines 11 - 13 | |
public function testGetCollectionOfTreasures(): void | |
{ | |
$this->browser() | |
->get('/api/treasures') | |
... line 18 | |
->assertJson() | |
; | |
} | |
} |
Cuando lo ejecutemos:
symfony php bin/phpunit
¡Pasa! ¡Genial! Sabemos que esta respuesta debe tener una propiedad hydra:totalItems
establecida en el número de resultados. Ahora mismo, nuestra base de datos está vacía... pero al menos podemos afirmar que coincide con cero.
Para ello, utiliza ->assertJsonMatches()
.
Se trata de un método especial de Browser que utiliza una sintaxis especial que nos permite leer diferentes partes del JSON. Profundizaremos en ello dentro de un minuto.
Pero éste es sencillo: afirma que hydra:totalItems
es igual a 0
:
... lines 1 - 8 | |
class DragonTreasureResourceTest extends KernelTestCase | |
{ | |
... lines 11 - 13 | |
public function testGetCollectionOfTreasures(): void | |
{ | |
$this->browser() | |
... lines 17 - 18 | |
->assertJson() | |
->assertJsonMatches('hydra:totalItems', 0) | |
; | |
} | |
} |
Cuando intentamos esto
symfony php bin/phpunit
¡Falla! Pero con un gran error:
mtdowling/jmespath.php
es necesario para buscar JSON
Ah, ¡necesitamos instalarlo! Copia la línea composer require
, busca tu terminal y ejecútalo:
composer require mtdowling/jmespath.php --dev
Esto de "JMESPath" es en realidad superguay: es un "lenguaje de consulta" para leer distintas partes de cualquier JSON. Por ejemplo, si éste es tu JSON y quieres leer la clave a
, sólo tienes que decir a
. Sencillo.
Pero también puedes hacer cosas más profundas, como a.b.c.d
. O ponte más loco: coge el índice 1
, o coge a.b.c
, luego el índice 0
, .d
, el índice 1
y luego el índice 0
. Incluso puedes cortar la matriz de diferentes maneras. Básicamente... puedes volverte loco.
Pero no vamos a perder la cabeza con esto. Es una sintaxis práctica... pero si las cosas se ponen demasiado complejas, siempre podemos probar el JSON manualmente, cosa que haremos dentro de un rato.
De todos modos, ahora que tenemos la biblioteca instalada, volvamos a ejecutar la prueba.
symfony php bin/phpunit
¡Sigue fallando! Con un extraño error:
Error de sintaxis en el carácter 5
hydra:totalItems
.
Por desgracia, el :
es un carácter especial dentro de JMESPath. Así que siempre que tengamos un :
, tenemos que poner comillas alrededor de esa clave:
... lines 1 - 8 | |
class DragonTreasureResourceTest extends KernelTestCase | |
{ | |
... lines 11 - 13 | |
public function testGetCollectionOfTreasures(): void | |
{ | |
$this->browser() | |
... lines 17 - 19 | |
->assertJsonMatches('"hydra:totalItems"', 0) | |
; | |
} | |
} |
No es lo ideal, pero no es un gran inconveniente.
Ahora, cuando lo probamos
symfony php bin/phpunit
¡Pasa!
Pero... ésta no es una prueba muy interesante: sólo estamos afirmando que no obtenemos nada de vuelta... porque la base de datos está vacía. Para que nuestra prueba sea real, necesitamos datos: necesitamos sembrar la base de datos con datos al inicio de la prueba.
Afortunadamente, Foundry lo hace muy sencillo. Arriba, llama aDragonTreasureFactory::createMany()
y creemos 5 tesoros. Ahora, abajo, afirma que obtenemos 5 resultados:
... lines 1 - 4 | |
use App\Factory\DragonTreasureFactory; | |
... lines 6 - 9 | |
class DragonTreasureResourceTest extends KernelTestCase | |
{ | |
... lines 12 - 14 | |
public function testGetCollectionOfTreasures(): void | |
{ | |
DragonTreasureFactory::createMany(5); | |
$this->browser() | |
... lines 20 - 22 | |
->assertJsonMatches('"hydra:totalItems"', 5) | |
... line 24 | |
; | |
} | |
} |
Así de sencillo. Y, de hecho, déjame que vuelva a poner nuestro volcado para que podamos ver el resultado:
... lines 1 - 9 | |
class DragonTreasureResourceTest extends KernelTestCase | |
{ | |
... lines 12 - 14 | |
public function testGetCollectionOfTreasures(): void | |
{ | |
... lines 17 - 18 | |
$this->browser() | |
... line 20 | |
->dump() | |
... line 22 | |
->assertJsonMatches('"hydra:totalItems"', 5) | |
... line 24 | |
; | |
} | |
} |
Pruébalo ahora:
symfony php bin/phpunit
¡Pasa! Y si miras hacia arriba, ¡sí! ¡La respuesta tiene 5 tesoros! Caray, qué fácil.
A continuación: utilicemos JMESPath para afirmar algo más desafiante. Luego retrocederemos y veremos cómo podemos profundizar en Browser para darnos una flexibilidad -y simplicidad- infinitas a la hora de probar JSON.
"Houston: no signs of life"
Start the conversation!
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^3.0", // v3.1.2
"doctrine/annotations": "^2.0", // 2.0.1
"doctrine/doctrine-bundle": "^2.8", // 2.8.3
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
"doctrine/orm": "^2.14", // 2.14.1
"nelmio/cors-bundle": "^2.2", // 2.2.0
"nesbot/carbon": "^2.64", // 2.66.0
"phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
"phpstan/phpdoc-parser": "^1.15", // 1.16.1
"symfony/asset": "6.2.*", // v6.2.5
"symfony/console": "6.2.*", // v6.2.5
"symfony/dotenv": "6.2.*", // v6.2.5
"symfony/expression-language": "6.2.*", // v6.2.5
"symfony/flex": "^2", // v2.2.4
"symfony/framework-bundle": "6.2.*", // v6.2.5
"symfony/property-access": "6.2.*", // v6.2.5
"symfony/property-info": "6.2.*", // v6.2.5
"symfony/runtime": "6.2.*", // v6.2.5
"symfony/security-bundle": "6.2.*", // v6.2.6
"symfony/serializer": "6.2.*", // v6.2.5
"symfony/twig-bundle": "6.2.*", // v6.2.5
"symfony/ux-react": "^2.6", // v2.7.1
"symfony/ux-vue": "^2.7", // v2.7.1
"symfony/validator": "6.2.*", // v6.2.5
"symfony/webpack-encore-bundle": "^1.16", // v1.16.1
"symfony/yaml": "6.2.*" // v6.2.5
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
"mtdowling/jmespath.php": "^2.6", // 2.6.1
"phpunit/phpunit": "^9.5", // 9.6.3
"symfony/browser-kit": "6.2.*", // v6.2.5
"symfony/css-selector": "6.2.*", // v6.2.5
"symfony/debug-bundle": "6.2.*", // v6.2.5
"symfony/maker-bundle": "^1.48", // v1.48.0
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/phpunit-bridge": "^6.2", // v6.2.5
"symfony/stopwatch": "6.2.*", // v6.2.5
"symfony/web-profiler-bundle": "6.2.*", // v6.2.5
"zenstruck/browser": "^1.2", // v1.2.0
"zenstruck/foundry": "^1.26" // v1.28.0
}
}