2
votes

Test unitaire Laravel - ajouter un cookie à la demande?

Je souhaite envoyer un cookie avec json POST:

public function handle($request, Closure $next)
{
    Log::debug('cookie', [$request->cookies]);

    //cookie validation

    return $next($request);
}

publication route a un middleware:

public function testAccessCookie()
{
    $response = $this->json('POST', route('publications'))->withCookie(Cookie::create('test'));
    //some asserts
}

Mais lors de l'exécution de testAccessCookie() , il y a [null] dans le journal. Aucun cookie attaché.

Qu'est-ce qui ne va pas?

Il n'y a pas de tel problème avec les requêtes réelles (dans le navigateur).


0 commentaires

3 Réponses :


5
votes

Vous pouvez ajouter des cookies aux appels lors des tests:

use Illuminate\Cookie\Middleware\EncryptCookies;

/**
 * @param array|string $cookies
 * @return $this
 */
protected function disableCookiesEncryption($name)
{
    $this->app->resolving(EncryptCookies::class,
        function ($object) use ($name)
        {
          $object->disableFor($name);
        });

    return $this;
}

Voir https://laravel.com/api/5.4/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.html#method_call

Cependant, vous rencontrerez un problème de cryptage des cookies. Vous pouvez désactiver temporairement les cookies pendant les tests avec:

$cookies = ['test' => 'value'];

$response = $this->call('POST', route('publications'), [], $cookies);

Ajout de $this->disableCookiesEncryption('test'); au début du test.

Vous devrez peut-être ajouter des en-têtes pour spécifier une réponse json.


0 commentaires

2
votes

Cela devrait fonctionner dans les versions récentes (Laravel 6):

Soit:

$cookies = ['test' => encrypt('value', false)];

$response = $this->call('POST', route('publications'), [], $cookies);

ou:

$this->disableCookieEncryption();


2 commentaires

Merci pour votre réponse! J'ai essayé de trouver une solution à notre problème de cryptage des cookies. Malheureusement, ce n'est pas dans la documentation officielle?


comment faire cela dans une demande de message



0
votes

Depuis Laravel 5.2, vous obtenez le \App\Http\Middleware\EncryptCookies::class défini par défaut dans le groupe de middleware web et il définira tous les cookies non chiffrés sur null.

Malheureusement, tous les cookies que vous envoyez avec $request->call() , $request->get() et $request->post() dans les tests unitaires sont généralement non chiffrés et rien dans la documentation officielle ne vous indique qu'ils doivent être chiffrés.

Si vous ne voulez pas appeler $request->disableCookieEncryption() chaque fois, en tant que solution permanente, vous pouvez simplement redéfinir la méthode isDisabled() dans App\Http\Middleware\EncryptCookies.php pour ignorer le cryptage des cookies pendant les tests unitaires.

Voici l'implémentation que j'ai faite pour Laravel 6.x, elle devrait également fonctionner sur les versions antérieures.

<?php

namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected $except = [
        //
    ];

    public function isDisabled($name)
    {
        if (app()->runningUnitTests()) {
            return true;    // Disable cookies encryption/decryption during unit testing
        }

        return parent::isDisabled($name);
    }
}


0 commentaires