> Manuales > Manual de Testing en Laravel

Cómo configurar la solicitud HTTP para testing con cookies o variables de sesión al ejecutar las pruebas en aplicaciones Laravel.

Hay ocasiones en las que necesitamos hacer un request un tanto especial, por ejemplo donde haya una cookie o una variable de sesión. Por ejemplo, queremos probar que, cuando existe esa cookie o esa variable de sesión, la página se comporta de un modo determinado.

En este post aprenderemos cómo definir estas configuraciones a nivel de testing, de modo que puedas probar de manera realista funcionalidades donde necesites este tipo de solicitudes.

Definir la existencia de cookies en una solicitud HTTP

Vamos a comenzar conociendo cómo configurar una solicitud HTTP con una cookie. Lo hacemos con el método withCookie(). Ese método pertenece a la clase TestCase que ofrece Laravel en la clase que usamos para extender en nuestras pruebas: Tests\TestCase.

Simplemente le enviaremos el nombre de la cookie que queremos crear y el valor que debe tener en esa solicitud.

$response = $this->withCookie('theme', 'dark')->get('/dashboard');

Gracias a la línea anterior de tu código de pruebas conseguirás que una solicitud HTTP se realice incorporando una cookie llamada "theme" con el valor "dark".

El método withCookie() también podría recibir un array asociativo de datos para añadir varias cookies a la vez. La clave del array sería el nombre de la cookie y el valor sería el dato a setear en ella: withCookie(['dato1' => 'valor1', 'dato2' => 'valor2').

Vamos a expandir este ejemplo viendo cómo testear esta funcionalidad, lo que nos dará una idea también sobre cómo podríamos luego incorporarla en nuestra aplicación, por medio de los artefactos disponibles en Laravel.

Vamos a definir las pruebas, en una clase nueva de pruebas que se encargue de probar esta funcionalidad. A esa clase le vamos a llamar ThemeCookieTest. Tendrá el siguiente código.

<?php

namespace Tests\Feature;

use Tests\TestCase;
use PHPUnit\Framework\Attributes\Test;

class ThemeCookieTest extends TestCase
{
    #[Test]
    public function without_theme_cookie_loads_light_theme(): void
    {
        $response = $this->get('/dashboard');

        $response->assertSee('<html class="light"', false);
    }

    #[Test]
    public function with_theme_cookie_loads_right_theme(): void
    {
        $response = $this->withCookie('theme', 'dark')->get('/dashboard');

        $response->assertSee('<html class="dark"', false);
    }
}

Si te fijas, nuestro primer método without_theme_cookie_loads_light_theme() no crea ninguna cookie y aún así se hace una aserción para verificar que el theme es "light".

En el segundo método with_theme_cookie_loads_right_theme() es donde vemos la aplicación de la cookie que define el tema (claro / oscuro). Verás que hemos asignado "dark" a la cookie "theme" y con ello luego hacemos la aserción para verificar si el tema está definido correctamente en la vista.

Al ver estas pruebas podemos deducir inmediatamente qué es lo que se debe desarrollar a continuación. Vemos que el tema predeterminado es "light" y que luego, si existe una cookie "theme" entonces se puede definir un tema a partir del valor de esa cookie. Esto es obvio, solo considero interesante remarcar este punto para que veamos que las pruebas pueden ser consideradas también como una documentación del software.

La implementación de esta funcionalidad en la aplicación no la vamos a ver en este manual porque sería irse mucho del tema, aunque ya adelantamos que lo lógico sería incorporarlo a partir de un middleware que pudiera procesarse en todas las solicitudes del grupo "web". De este modo tendríamos una capa capaz de procesar todas las llamadas a páginas sin tener que agregar código extra en cada uno de los controladores que devuelven HTML.

Cómo añadir sesiones a una request para pruebas en Laravel

Quizás las cookies no se usen tan frecuentemente, aunque tienen aplicaciones muy útiles como la que acabamos de ver. Sin embargo, las sesiones en la web sí que son fundamentales para muchos procesos a la hora de construir aplicaciones.

Un ejemplo clásico sería construir un carrito de la compra. A lo largo de toda la visita a un sitio el usuario puede ir introduciendo productos en un carrito y éstos deben memorizarse de algún modo durante todas las páginas de su recorrido por la tienda. Para ello las sesiones son el soporte clásico.

Por supuesto, para probar si el carrito de la compra está funcionando correctamente necesitaremos que ciertas solicitudes HTTP tengan algunos datos creados en la sesión y esto lo podemos conseguir de manera muy similar a lo que hemos visto con las cookies.

$response = $this->withSession('cart' => $cartData)->get('/carrito');

Ahora vamos a ver las pruebas que podríamos hacer para verificar la página que nos muestra el carrito de la compra.

Igual que withCookie(), al método withSession() le podemos pasar un array asociativo si queremos enviarle varias variables de sesión al mismo tiempo. Incluso aunque solo tengamos una única variable de sesión lo podemos hacer así por mantener un uso consistente de withSession(), como vamos a ver en las siguientes pruebas.

<?php

namespace Tests\Feature;

use Tests\TestCase;
use PHPUnit\Framework\Attributes\Test;

class CartTest extends TestCase
{
    #[Test]
    public function it_shows_empty_cart_message_when_cart_is_empty(): void
    {
        $response = $this->get('/carrito');
        $response->assertStatus(200);
        $response->assertSee('Tu carrito está vacío');
    }

    #[Test]
    public function it_shows_cart_with_items_in_session()
    {
        $cartData = [
            ['id' => 1, 'name' => 'Ordenador HP Folio 13', 'price' => 1049.95],
            ['id' => 2, 'name' => 'Ratón Logitech MX', 'price' => 95],
        ];

        $response = $this
            ->withSession(['cart' => $cartData])
            ->get('/carrito');

        $response->assertStatus(200)
                 ->assertSeeInOrder(['Ordenador HP Folio 13','1049,95'])
                 ->assertSeeInOrder(['Ratón Logitech MX', '95,00']);
    }
}

En el primer método estamos probando que cuando no tenemos datos del carrito, porque ni siquiera existe esa variable de sesión, nos muestra un mensaje indicando que el carrito está vacío.

En el segundo método de test creamos varios productos y hacemos un request enviando ese array de valores como datos del carrito.

Luego verificamos que se encuentra el nombre de cada uno de los productos del carrito. Además verificamos que el precio se muestra con el formato adecuado para importes de monedas en español. Estas dos verificaciones se pueden hacer de una sola vez con el método asertSeeInOrder() que nos asegura que esos dos textos aparecen en la página en el orden en el que los hemos escrito en el array.

Te dejamos como trabajo para ti escribir el código de la página que muestra el carrito y que pueda dar por buenas las pruebas anteriores. Por nuestra parte en el próximo artículo cambiaremos de tema para hablar del tratamiento y la comprobación de excepciones en las pruebas Laravel.

Miguel Angel Alvarez

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

Manual