【问题标题】:In Laravel 4 unit-test, how to set cookie in request?在 Laravel 4 单元测试中,如何在请求中设置 cookie?
【发布时间】:2016-03-17 14:51:09
【问题描述】:

在我的 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:

以上没有没有工作。

【问题讨论】:

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


    【解决方案1】:

    您必须将 cookie 变量与返回响应放在一起,然后它才能工作

    代码看起来像

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

    返回 $response;

    【讨论】:

    • 这就是您将 cookie 连同他的响应一起发送回客户端的方式。我需要一种在 request 中设置 cookie 的方法,以便我的代码可以读取/处理它。
    • 不,据我所知,laravel 仅在附加了 cookie 时才设置 cookie return 。在您的情况下,您可以在代码中使用该变量,然后发送带有 cookie 的变量作为响应(根据您的代码流/条件)
    【解决方案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

    【讨论】:

    • 我收到此错误:ErrorException: Undefined property: ExampleTest::$client
    • 你的ExampleTest 扩展Illuminate\Foundation\Testing\TestCase 吗?
    • 是的,它确实扩展了该类。
    【解决方案3】:

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

    【讨论】:

    • 感谢您的参考和详细解释。 :D 遗憾的是,您引用的方法似乎没有出现在 Laravel 4 中,它通过 trait Concerns\MakesHttpRequests 首次出现在 v5.2.0 中。很高兴他们添加了它,但在 Laravel 4 中,看起来我们仍然坚持使用 getCookieJar() 解决方法。
    • @DavidWeinraub 你是对的。我将进行编辑以明确这一点。但我会把答案留给运行更新版本 laravel 的人。
    【解决方案4】:

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

    【讨论】:

    • 感谢您的参考和详细解释。 :D 遗憾的是,您引用的方法似乎没有出现在 Laravel 4 中,它通过特征 Concerns\MakesHttpRequests 首次出现在 v5.2.0 中。很高兴他们添加了它,但在 Laravel 4 中,看起来我们仍然坚持使用 getCookieJar() 解决方法。
    【解决方案5】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-29
      • 2016-09-23
      • 2019-08-10
      • 1970-01-01
      • 2018-09-02
      • 2021-10-03
      • 2021-05-12
      • 2016-06-01
      相关资源
      最近更新 更多