> Manuales > Manual de Testing en Laravel

Cómo hacer testing de los errores de validación generados al validar los datos con las funciones de validación de Laravel.

Cómo testear los errores de las validaciones en Laravel

En un artículo anterior vimos cómo podemos testear solicitudes HTTP de tipo POST, en las que enviamos datos que serán recibidos en el controlador. En realidad el procedimiento es muy sencillo porque simplemente debemos usar el método post() enviando, además de la URL a validar, el array de datos que se van a recibir en cada caso de prueba.

Hasta ahí todo bien pero, ¿qué pasa si quiero validar que ciertos juegos de datos enviados deben producir errores de validación? ¿o que ciertos datos enviados no producen errores de validación? Para ello Laravel también nos puede ayudar bastante, como veremos en este artículo.

Aserciones de validación en Laravel

En Laravel tenemos unas aserciones especializadas para las validaciones generadas con el sistema de validación del propio framework.

Son aserciones muy sencillas de utilizar, como vamos a comprobar enseguida.

Aserción assertValid()

Esta aserción es muy sencilla de utilizar. Simplemente comprueba que no se han producido errores de validación en la respuesta de la ruta que estamos testeando.

#[Test]
public function data_00_00_is_valid(): void
{
    $formData = [
        'start_hour' => '00',
        'start_minute' => '00',
    ];

    $response = $this->post('/panel/store', $formData);

    $response->assertValid();
}

Solo ten en cuenta que si esa ruta no está haciendo ninguna validación, assertValid() te dirá siempre que la respuesta es válida. Así que para que está aserción pueda tener algún valor en nuestro código tenemos que asegurarnos de validar algo, sino, simplemente pasará el test.

También podemos decirle qué datos en concreto deseamos verificar que no dan errores de validación, por si solo queremos verificar unos determinados campos.

$response->assertValid(['start_hour']);

Aserción assertInvalid()

Esta aserción hace el trabajo justamente contrario, verificar que ciertos valores nos devuelven errores de validación.

#[Test]
public function data_24_00_is_invalid(): void
{
    $formData = [
        'start_hour' => '24',
        'start_minute' => '00',
    ];

    $response = $this->post('/panel/store', $formData);

    $response->assertInvalid();
}

Para que esta regla de aserción funcione el controlador Laravel necesita enviar errores de validación, por lo que resulta conveniente usarla cuando un controlador se supone que debe validar alguna cosa.

Así que si nuestro controlador estaba como lo teníamos en el artículo anterior (sin hacer uso del sistema de validación de Laravel) la prueba fallará. Enseguida veremos un código de controlador para pasar la prueba.

Podemos indicar también que queremos verificar que solamente ciertos campos son inválidos, de este modo:

$response->assertInvalid(['start_hour']);

Incluso, además de verificar que el campo es inválido, podemos verificar que el mensaje de error de validación es uno determinado.

$response->assertInvalid(['start_hour' => 'The start hour field is required.']);

Aún hay más alternativas, ya que podríamos escribir solo una parte del mensaje de error de la validación:

$response->assertInvalid(['start_hour' => 'required']);

Con respecto a la verificación de los mensajes de error de validación debes de tener en cuenta que estos mensajes podrían cambiar a lo largo del tiempo, por ejemplo cuando localizas la aplicación Laravel para distintos idiomas. En principio los errores de validación deberían ser estables a lo largo del tiempo pero si piensas que pueden haber cambios con el tiempo quizás no sea tan buena idea comprobar esos mensajes.

Mezclar las aserciones de validación de Laravel para comprobaciones más detalladas

En este ejemplo de método de test combinamos diversas aserciones en las que involucran validaciones positivas y negativas de los datos que se envían por post:

#[Test]
public function has_validation_error_when_hour_is_missing()
{
    $formData = [
        'start_minute' => '15',
    ];

    $response = $this->post('/panel/store', $formData);
    $response->assertValid(['start_minute']);
    $response->assertInvalid(['start_hour' => 'The start hour field is required.']);
    $response->assertStatus(302);
}

Usando el assert assertSessionHasErrors()

Cuando quieres verificar que ciertas entradas de datos producen errores de validación, otra posibilidad de encarar esta comprobación sería usar la aserción assertSessionHasErrors().

Solo hay un matiz que queremos comentar, pero antes veamos un ejemplo en el siguiente método.

#[Test]
public function has_validation_error_when_minute_is_invalid()
{
    $formData = [
        'start_hour' => '08',
        'start_minute' => '10', // Minutos inválidos
    ];

    $response = $this->post('/panel/store', $formData);

    $response->assertStatus(302);
    $response->assertSessionHasErrors(['start_minute']);
}

Cómo estás observando, hemos usado assertSessionHasErrors() indicando los campos en los que esperamos se encuentren variables de sesión que han producido errores.

De paso, también has observado que hemos usado una aserción adicional, que agrega una comprobación extra a nuestras pruebas y es assertStatus(302). Esta aserción comprueba que el status de la respuesta del servidor es 302, la típica que manda Laravel de manera predeterminada cuando la validación ha dado un fallo.

Técnicamente 302 es una redirección. Es porque el sistema de validación te reenvía al formulario anterior, para mostrarlo de nuevo con los errores de validación encontrados.

También podríamos indicar a assertSessionHasErrors() el mensaje exacto que se debe encontrar en la variable de sesión.

#[Test]
public function has_validation_error_when_hour_is_out_of_range()
{
    $formData = [
        'start_hour' => '25',
        'start_minute' => '15',
    ];

    $response = $this->post('/panel/store', $formData);

    $response->assertStatus(302);
    $response->assertSessionHasErrors(['start_hour' => 'The start hour field format is invalid.']);
}

En este punto hay un par de detalles importante que comentar:

Conclusión

Con lo que hemos aprendido en este artículo ahora puedes hacer el test del sistema de validaciones de Laravel, detectando que ciertos juegos de datos producen determinados errores de validación, o que no se generen errores de validación. Además, hemos conocido los métodos principales de test para las validaciones, distinguiendo las diferencias que tienen cuando estás realizando salidas de datos en formato JSON o mediante el mecanismo de los sitios tradicionales, que funcionan con variables de sesión.

En el siguiente artículo vamos a ver una práctica de repaso a algo que existe en PHPUnit que son los Data Providers y veremos cómo nos podemos valer de ellos para mejorar el diseño de las clases de test, cuando trabajamos con validaciones.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual