在Laravel 4单元测试中,如何在请求中设置cookie?

时间:2015-12-11 16:09:39

标签: php unit-testing laravel cookies laravel-4

在我的Laravel 4应用程序中,我希望测试特定端点是否在请求中检测并正确响应cookie。因此,在我的单元测试中,我希望在请求中设置一个cookie,然后对响应执行标准断言。

我在单元测试中的调用形式为:

$response = $this->client->request($method, $endpoint, $params, $files, $server);

我已为$method$endpoint$params以及空$files$server指定了正确的值。

我尝试了很多变体,将Cookie值放在$params$server下的各种键下,但到目前为止,没有运气看到Cookie出现在Cookie:get('myname)下的控制器中。

如何设置名称为' myname'的Cookie和价值' myvalue'在单元测试的请求中?

更新

我想我可以简单地在请求中添加标题:

Cookie: myname=myvalue

但我必须相信有更多类似Laravel的方式。

更新2:

上面做了工作。

5 个答案:

答案 0 :(得分:4)

看起来我们可以在扩展Illuminate\Foundation\Testing\TestCase的测试中执行以下操作:

$this->client->getCookieJar()->set(
    new \Symfony\Component\BrowserKit\Cookie('myname', 'myvalue')
);

然后,cookie将通过标准在控制器中公开:

$cookie = Cookie::get('myname'); // $cookie gets 'myvalue'

(通过Laravel.io

答案 1 :(得分:1)

  

编辑:仅适用于LARAVEL 5.2或更高版本

您可以使用Documentation for TestCase

中显示的call()方法设置Cookies。

我最近使用了类似的东西。这是一个示例:

$cookies = ['cookie_name' => 'cookie_value'];
$response = $this->call("get", 'target/url/for/request', [], $cookies);

这是Laravel框架Github上的additional issue thread,有人对如何称呼它有些困惑。这进一步巩固了我的知识。希望这会有所帮助!

编辑:

laravel丢弃无法解密的cookie似乎存在问题。注意这一点。 Here is a Link给遇到此问题的人。

他们建议的解决方案(如果此链接消失):

  

似乎问题在于cookie加密。 Laravel会删除无法解密的Cookie。由于测试cookie不是由laravel创建的(我只是使用数组来测试cookie,如上一篇文章所示),因此它们没有被加密,因此将被删除。我可以想到两个解决方案。

     
      
  1. 只需从app / Http / Kernel.php中的列表中删除cookie中间件。所有cookie都会按原样发送到客户端或从客户端接收。如果您不需要加密或想在客户端读取一些cookie,那么这是一个不错的解决方案。

  2.   
  3. 编辑中间件,以使其在测试期间不会加密或解密cookie。只需添加代码即可处理检查环境的功能,如果环境正在测试,则无需执行任何操作即可继续。该中间件位于Illuminate / Cookie / Middleware / EncryptCookie.php中。因此,框架更新将撤消您对该文件的编辑。如果需要加密,这是唯一的解决方案。

  4.   

答案 2 :(得分:1)

我对需要非常相似的功能进行了测试,我使用$ this-> call()函数进行了测试

$this->call($method, $url, $parameters = [], $cookies = [“name”=> Illuminate\Support\Facades\Crypt::encryptString(”Leonardo”)], $files = [], $server = [], $content = null);

如果您需要了解其工作原理,只需查找以下文件即可:

Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php

答案 3 :(得分:0)

你必须把cookie变量和返回响应放在一起然后才能工作

代码看起来像

$ response-> withCookie(cookie('name','value',$ minutes));

返回$ response;

答案 4 :(得分:0)

正如Noah Gary所写,要小心,因为自5.2版Laravel以来,Web组中都有一个默认的中间件,它将重置在任何$request->call()函数中传递的所有未加密的cookie。 Cookies标头不会重置,但默认情况下,所有cookie值都将设置为null

选中Kernel.php,您将在\App\Http\Middleware\EncryptCookies::class中间件组中找到web。您可以直接禁用它,但不建议这样做。

如果您不想每次都调用$request->disableCookieEncryption(),那么作为永久解决方案,您只需在isDisabled()中重新定义App\Http\Middleware\EncryptCookies.php方法即可在单元测试期间忽略cookie加密。

这是我为Laravel 6.x进行的实现,它也应该在较早的版本上工作。

<?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);
    }
}