在我的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:
上面做了不工作。
答案 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,如上一篇文章所示),因此它们没有被加密,因此将被删除。我可以想到两个解决方案。
只需从app / Http / Kernel.php中的列表中删除cookie中间件。所有cookie都会按原样发送到客户端或从客户端接收。如果您不需要加密或想在客户端读取一些cookie,那么这是一个不错的解决方案。
编辑中间件,以使其在测试期间不会加密或解密cookie。只需添加代码即可处理检查环境的功能,如果环境正在测试,则无需执行任何操作即可继续。该中间件位于Illuminate / Cookie / Middleware / EncryptCookie.php中。因此,框架更新将撤消您对该文件的编辑。如果需要加密,这是唯一的解决方案。
答案 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);
}
}