# Pruebas HTTP

# Introducción

Laravel proporciona una API muy fluida para hacer solicitudes HTTP a tu aplicación y examinar la salida. Por ejemplo, echemos un vistazo a la prueba definida a continuación:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    /**
    * A basic test example.
    *
    * @return void
    */
    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

El método get simula una solicitud GET dentro de la aplicación, mientras que el método assertStatus comprueba que la respuesta devuelta debería tener el código de estado HTTP dado. Además de esta sencilla aserción, Laravel también contiene una variedad de aserciones para inspeccionar de la respuesta los encabezados, contenidos, estructura JSON y más.

# Personalizando encabezados de solicitud

Puedes usar el método withHeaders para personalzar los encabezados de la solicitud antes que sean enviados a la aplicación. Esto permitirá que agregues algunos encabezados personalizados de tu preferencia a la solicitud:

<?php

class ExampleTest extends TestCase
{
    /**
    * A basic functional test example.
    *
    * @return void
    */
    public function testBasicExample()
    {
        $response = $this->withHeaders([
            'X-Header' => 'Value',
        ])->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(200)
            ->assertJson([
                'created' => true,
            ]);
    }
}

TIP

El middleware CSRF es automáticamente deshabilitado cuando se ejecutan las pruebas.

# Depurando respuestas

Luego de hacer una solicitud de prueba a tu aplicación, los métodos dump y dumpHeaders pueden ser usados para examinar y depurar el contenido de la respuesta:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    /**
    * A basic test example.
    *
    * @return void
    */
    public function testBasicTest()
    {
        $response = $this->get('/');
        $response->dumpHeaders();
        $response->dump();
    }
}

# Sesión y autenticación

Laravel proporciona varias funciones helper para trabajar con la sesión durante las pruebas HTTP. Primero, puedes colocar los datos de la sesión en un arreglo dado usando el método withSession. Esto es útil para cargar la sesión con los datos antes de realizar una solicitud a tu aplicación:

<?php

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $response = $this->withSession(['foo' => 'bar'])
                            ->get('/');
    }
}

Un uso común de la sesión es para mantener el estado del usuario autenticado. El método helper actingAs proporciona una foma sencilla de autenticar un usuario dado como el usuario actual. Por ejemplo, podemos usar un model factory para generar y autenticar un usuario:

<?php

use App\User;

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $user = factory(User::class)->create();

        $response = $this->actingAs($user)
                            ->withSession(['foo' => 'bar'])
                            ->get('/');
    }
}

También puedes especificar que "guard" debe ser usado para autenticar el usuario dado al pasar el nombre del guard como segundo argumento del método actingAs:

$this->actingAs($user, 'api')

# Probando APIs JSON

Laravel también proporciona varios helpers para probar APIs JSON y sus respuestas. Por ejemplo, los métodos json, get, post, put, patch y delete pueden ser usados para hacer solicitudes con varios verbos HTTP. También puedes pasar datos y encabezados fácilmente a estos métodos. Para empezar, vamos a escribir una prueba para hacer una solicitud POST a /user y comprobar que los datos esperados fueron devueltos:

<?php

class ExampleTest extends TestCase
{
    /**
    * A basic functional test example.
    *
    * @return void
    */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(200)
            ->assertJson([
                'created' => true,
            ]);
    }
}

TIP

El método assertJson convierte la respuesta a un arreglo y utiliza PHPUnit::assertArraySubset para verificar que el arreglo dado exista dentro de la respuesta JSON devuelta por la aplicación. Así, si hay otras propiedades en la respuesta JSON, esta prueba aún pasará siempre y cuando el fragmento dado esté presente.

# Verificando una coincidencia JSON exacta

Si prefieres verificar que el arreglo dado esté contenido exactamente en la respuesta JSON devuelta por la aplicación, deberías usar el método assertExactJson:

<?php

class ExampleTest extends TestCase
{
    /**
    * A basic functional test example.
    *
    * @return void
    */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(200)
            ->assertExactJson([
                'created' => true,
            ]);
    }
}

# Probando subidas de archivos

La clase Illuminate\Http\UploadedFile proporciona un método fake el cual puede ser usado para generar archivos de prueba o imágenes para prueba. Esto, combinado con el método fake de la clase facade Storage simplifica grandemente la prueba de subidas de archivos. Por ejemplo, puedes combinar estas dos características para probar fácilmente un formulario de subida de un avatar:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    public function testAvatarUpload()
    {
        Storage::fake('avatars');

        $file = UploadedFile::fake()->image('avatar.jpg');

        $response = $this->json('POST', '/avatar', [
            'avatar' => $file,
        ]);

        // Assert the file was stored...
        Storage::disk('avatars')->assertExists($file->hashName());

        // Assert a file does not exist...
        Storage::disk('avatars')->assertMissing('missing.jpg');
    }
}

# Personalización de archivo fake

Al momento de crear archivos usando el método fake, puedes especificar el ancho, la altura y el tamaño de la imagen con el propósito de probar mejor tus reglas de validación:

UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

Además de crear imágenes, puedes crear archivos de cualquier otro tipo usando el método create:

UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

# Aserciones disponibles

# Aserciones de respuesta

Laravel proporciona una variedad de métodos de aserción personalizados para tus pruebas PHPUnit. Estas aserciones pueden ser accedidas en la respuesta que es retornada por los métodos de prueba json, get, post, put y delete:

# assertCookie

Comprueba que la respuesta contenga el cookie dado:

$response->assertCookie($cookieName, $value = null);

# assertCookieExpired

Comprueba que la respuesta contenga el cookie dado y que esté vencido:

$response->assertCookieExpired($cookieName);

# assertCookieNotExpired

Comprueba que la respuesta contenga la cookie dada y que no haya expirado:

$response->assertCookieNotExpired($cookieName);

# assertCookieMissing

Comprueba que la respuesta no contenga el cookie dado:

$response->assertCookieMissing($cookieName);

# assertDontSee

Comprueba que la cadena dada no esté contenida dentro de la respuesta:

$response->assertDontSee($value);

# assertDontSeeText

Comprueba que la cadena dada no esté contenida dentro del texto de la respuesta:

$response->assertDontSeeText($value);

# assertExactJson

Comprueba que la respuesta contenga una coincidencia exacta de los datos JSON dados:

$response->assertExactJson(array $data);

# assertForbidden

Comprueba que la respuesta tenga un código de estado "prohibido":

$response->assertForbidden();

# assertHeader

Comprueba que el encabezado dado esté presente en la respuesta:

$response->assertHeader($headerName, $value = null);

# assertHeaderMissing

Comprueba que el encabezado dado no esté presente en la respuesta:

$response->assertHeaderMissing($headerName);

# assertJson

Comprueba que la respuesta contenga los datos JSON dados:

$response->assertJson(array $data);

# assertJsonCount

Comprueba que la respuesta JSON tenga un arreglo con el número esperado de elementos en la llave dada:

$response->assertJsonCount($count, $key = null);

# assertJsonFragment

Comprueba que la respuesta contenga el fragmento JSON dado:

$response->assertJsonFragment(array $data);

# assertJsonMissing

Comprueba que la respuesta no contenga el fragmento JSON dado:

$response->assertJsonMissing(array $data);

# assertJsonMissingExact

Comprueba que la respuesta no contenga el fragmento exacto JSON:

$response->assertJsonMissingExact(array $data);

# assertJsonMissingValidationErrors

Comprueba que la respuesta no contenga errores de validación JSON para la llaves dadas:

$response->assertJsonMissingValidationErrors($keys);

# assertJsonStructure

Comprueba que la respuesta tenga una estructura JSON dada:

$response->assertJsonStructure(array $structure);

# assertJsonValidationErrors

Comprueba que la respuesta tenga los errores de validación JSON dados:

$response->assertJsonValidationErrors(array $data);

# assertLocation

Comprueba que la respuesta tenga el valor URI dado en el encabezado Location:

$response->assertLocation($uri);

# assertNotFound

Comprueba que la respuesta tenga un código de estado "no encontrado":

$response->assertNotFound();

# assertOk

Comprueba que la respuesta tenga un código de estado 200:

$response->assertOk();

# assertPlainCookie

Comprueba que la respuesta contenga el cookie dado (desencriptado):

$response->assertPlainCookie($cookieName, $value = null);

# assertRedirect

Comprueba que la respuesta es una redirección a una URI dada:

$response->assertRedirect($uri);

# assertSee

Comprueba que la cadena dada esté contenida dentro de la respuesta:

$response->assertSee($value);;

# assertSeeInOrder

Comprueba que las cadenas dadas estén en orden dentro de la respuesta:

$response->assertSeeInOrder(array $values);

# assertSeeText

Comprueba que la cadena dada esté contenida dentro del texto de la respuesta:

$response->assertSeeText($value);

# assertSeeTextInOrder

Comprueba que las cadenas dadas estén en orden dentro del texto de respuesta:

$response->assertSeeTextInOrder(array $values);

# assertSessionHas

Comprueba que la sesión contenga la porción dada de datos:

$response->assertSessionHas($key, $value = null);

# assertSessionHasAll

Comprueba que la sesión tenga una lista dada de valores:

$response->assertSessionHasAll(array $data);

# assertSessionHasErrors

Comprueba que la sesión contenga un error para el campo dado:

$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');

# assertSessionHasErrorsIn

Comprueba que la sesión tenga los errores dados:

$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);

# assertSessionHasNoErrors

Comprueba que la sesión no contenga errores:

$response->assertSessionHasNoErrors();

# assertSessionDoesntHaveErrors

Comprueba que la sesión no contenga errores para las llaves dadas:

$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');

# assertSessionMissing

Comprueba que la sesión no contenga la llave dada:

$response->assertSessionMissing($key);

# assertStatus

Comprueba que la respuesta tenga un código dado:

$response->assertStatus($code);

# assertSuccessful

Comprueba que la respuesta tenga un código de estado de éxito (200):

$response->assertSuccessful();

# assertUnauthorized

Comprueba que la respuesta tiene un código de estado sin autorización (401):

$response->assertUnauthorized();

# assertViewHas

Comprueba que la vista de la respuesta dada contiene los valores indicados:

$response->assertViewHas($key, $value = null);

# assertViewHasAll

Comprueba que la vista de la respuesta tiene una lista de datos:

$response->assertViewHasAll(array $data);

# assertViewIs

Comprueba que la vista dada fue retornada por la ruta:

$response->assertViewIs($value);

# assertViewMissing

Comprueba que a la vista de la respuesta le está faltando una porción de datos enlazados:

$response->assertViewMissing($key);

# Aserciones de autenticación

Laravel también proporciona una variedad de aserciones relacionadas con la autenticación para tus pruebas PHPUnit:

Método Descripción
$this->assertAuthenticated($guard = null); Comprueba que el usuario está autenticado.
$this->assertGuest($guard = null); Comprueba que el usuario no está autenticado.
$this->assertAuthenticatedAs($user, $guard = null); Comprueba que el usuario dado está autenticado.
$this->assertCredentials(array $credentials, $guard = null); Comprueba que las credenciales dadas son válidas.
$this->assertInvalidCredentials(array $credentials, $guard = null); Comprueba que las credenciales dadas no son válidas.