Laravel ofrece una robusta suite de herramientas para pruebas que facilita garantizar que el comportamiento de tu aplicación sea el esperado. Entre las muchas herramientas disponibles, el método assertJson
es uno de los más utilizados para validar respuestas en formato JSON. Sin embargo, Laravel también proporciona una forma más avanzada y flexible de realizar estas validaciones a través de la clase AssertableJson
. En este artículo, aprenderás a usar ambos enfoques para realizar pruebas de JSON en Laravel.
assertJson
?
El método assertJson
en Laravel permite verificar que una respuesta JSON contiene un conjunto específico de datos o estructura. Este método es ideal para realizar comprobaciones simples o parciales de respuestas JSON en tus pruebas.
assertJson
Supongamos que tienes una API que devuelve una lista de usuarios. El controlador puede ser algo similar a esto:
public function index()
{
return response()->json([
'users' => [
['id' => 1, 'name' => 'Juan'],
['id' => 2, 'name' => 'María'],
]
]);
}
Podrías escribir una prueba utilizando assertJson
de la siguiente manera:
public function testIndexReturnsUsers()
{
$response = $this->get('/api/users');
$response->assertStatus(200)
->assertJson([
'users' => [
['id' => 1, 'name' => 'Juan'],
['id' => 2, 'name' => 'María'],
]
]);
}
Aquí, la prueba verifica que la respuesta contiene exactamente una lista de usuarios con los valores esperados de id
y name
.
AssertableJson
Aunque assertJson
es muy útil, puede volverse algo limitado cuando necesitas realizar validaciones más complejas o dinámicas. Laravel introduce la clase AssertableJson
, que te permite realizar validaciones más detalladas y expresivas sobre el contenido de la respuesta JSON.
AssertableJson
permite usar métodos como where
, has
, y etc
para crear pruebas más flexibles y específicas sobre la estructura y contenido del JSON. Veamos cómo funciona.
AssertableJson
Imagina que quieres validar no solo los valores específicos de los usuarios, sino también asegurarte de que ciertos campos existen y tienen el tipo de datos correcto. Aquí es donde entra en juego AssertableJson
:
use Illuminate\Testing\Fluent\AssertableJson;
public function testIndexReturnsCorrectJsonStructure()
{
$response = $this->get('/api/users');
$response->assertJson(function (AssertableJson $json) {
$json->has('users', 2) // Verifica que el array 'users' tiene exactamente 2 elementos
->first(function (AssertableJson $json) {
$json->where('id', 1) // Verifica que el primer usuario tiene id = 1
->where('name', 'Juan') // Verifica que el primer usuario tiene name = 'Juan'
->etc(); // Acepta que puede haber otros campos adicionales no verificados
});
});
}
En este ejemplo:
has('users', 2)
asegura que el JSON contiene exactamente dos usuarios en el array users
.
first()
permite inspeccionar el primer elemento del array y validar sus valores con where
.
etc()
indica que puede haber más campos en el JSON que no estamos validando explícitamente, pero que no nos importa en este caso.
AssertableJson
Vamos a suponer que tienes una respuesta más compleja y quieres verificar que el campo id
es un UUID y que el campo name
es una cadena de texto. También queremos validar que el JSON contiene un número específico de elementos en su clave data
. Aquí es donde AssertableJson
realmente brilla:
use Illuminate\Testing\Fluent\AssertableJson;
public function testApiReturnsCorrectDataStructure()
{
$expectedAmount = 3;
$response = $this->get('/api/data');
$response->assertJson(function (AssertableJson $json) use ($expectedAmount) {
$json->where('success', true) // Verifica que el campo 'success' es true
->has('data', $expectedAmount) // Verifica que hay exactamente $expectedAmount elementos en 'data'
->has('data.0', function (AssertableJson $json) { // Verifica el primer elemento de 'data'
$json->where('id', fn(string $id) => str($id)->isUuid()) // Verifica que 'id' es un UUID
->whereType('name', 'string'); // Verifica que 'name' es de tipo string
});
});
}
En este caso:
where('success', true)
valida que el campo success
sea true
.
has('data', $expectedAmount)
valida que el array data
contiene exactamente la cantidad esperada de elementos.
has('data.0')
permite navegar dentro de un array de datos anidados. En este ejemplo, validamos que el primer elemento (data.0
) tiene un id
que es un UUID y que el campo name
es de tipo cadena.
Este enfoque te permite escribir pruebas más dinámicas y robustas, verificando no solo los valores, sino también los tipos de datos y la estructura.
assertJson
y AssertableJson
assertJson
assertJson
es la herramienta más directa.
AssertableJson
AssertableJson
son más expresivas y claras, lo que facilita el mantenimiento de pruebas complejas.
assertJson
cuando necesitas realizar comprobaciones simples sobre la estructura JSON, como asegurarte de que ciertos valores existen o que ciertos campos contienen los valores esperados.
AssertableJson
cuando necesites realizar validaciones más avanzadas sobre la estructura, tipos de datos, o cuando quieras hacer uso de funciones de callback para validar condiciones más complejas.
Las pruebas en Laravel son esenciales para asegurar la calidad de tu aplicación, y el framework proporciona herramientas potentes para realizar pruebas sobre respuestas JSON. Tanto assertJson
como AssertableJson
son métodos útiles para verificar que tu API responde con los datos correctos, pero cada uno tiene sus ventajas y usos específicos.
Mientras que assertJson
es perfecto para pruebas rápidas y simples, AssertableJson
te ofrece la flexibilidad necesaria para pruebas más detalladas y dinámicas. Al combinar ambos métodos, puedes cubrir un amplio espectro de casos de prueba y garantizar que tu aplicación funcione correctamente en todas las situaciones.
Mantén tus pruebas organizadas, utiliza las herramientas adecuadas y no dudes en usar AssertableJson
cuando enfrentes situaciones complejas en las que assertJson
podría quedarse corto. ¡Con esto, tu aplicación estará mucho mejor preparada para enfrentar cualquier reto!
Jorge García
Fullstack developer