繁体   English   中英

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

[英]In Laravel 4 unit-test, how to set cookie in request?

在我的 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”且值为“myvalue”的 cookie?

更新:

我想我可以简单地向请求添加一个标头:

Cookie: myname=myvalue

但我必须相信有一种更像 Laravel 的方式来做到这一点。

更新 2:

以上没有工作。

看起来我们可以在扩展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

编辑:这只适用于 Laravel 5.2 或更高版本

您可以使用TestCase 文档中显示的 call() 方法设置 Cookie

我最近使用了类似的东西。 下面是一个例子:

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

这是 Laravel Framework Github 上的一个附加问题线程,有人对如何调用它有些困惑。 这进一步巩固了我的知识。 希望这可以帮助!

编辑:

laravel 丢弃无法解密的 cookie 似乎存在问题。 小心这一点。 这是遇到此问题的人的链接

他们建议的解决方案(以防此链接失效):

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

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

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

我对需要非常相似的功能进行了测试。 我使用$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

您必须将 cookie 变量与返回响应放在一起,然后它就会起作用

代码看起来像

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

返回 $response;

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

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

如果您不想每次都调用$request->disableCookieEncryption() ,作为永久解决方案,您可以简单地重新定义App\\Http\\Middleware\\EncryptCookies.phpisDisabled()方法以在单元测试期间忽略 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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM