我想发送带有JSON POST的cookie:
public function testAccessCookie()
{
$response = $this->json('POST', route('publications'))->withCookie(Cookie::create('test'));
//some asserts
}
发布路线具有一些中间件:
public function handle($request, Closure $next)
{
Log::debug('cookie', [$request->cookies]);
//cookie validation
return $next($request);
}
但是在运行testAccessCookie()
时,日志中有[null]
。没有附加Cookie。
怎么了?
真正的(浏览器中)请求没有这种问题。
答案 0 :(得分:1)
您可以向测试中的通话添加cookie:
$cookies = ['test' => 'value'];
$response = $this->call('POST', route('publications'), [], $cookies);
但是,您将遇到Cookie加密问题。您可以使用以下方法在测试过程中暂时禁用Cookie:
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;
}
在测试开始时添加$this->disableCookiesEncryption('test');
。
您可能需要添加标头以指定json响应。
答案 1 :(得分:1)
这应该在最新版本(Laravel 6)中起作用:
要么:
$this->disableCookieEncryption();
或:
$cookies = ['test' => encrypt('value', false)];
$response = $this->call('POST', route('publications'), [], $cookies);
答案 2 :(得分:0)
从Laravel 5.2开始,您将获得\App\Http\Middleware\EncryptCookies::class
中间件组中默认定义的web
中间件,它将所有未加密的cookie设置为null。
不幸的是,您在单元测试中使用$request->call()
,$request->get()
和$request->post()
发送的所有cookie通常都是未加密的,并且官方文档中没有任何内容表明您需要对其进行加密。
如果您不想每次都调用$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);
}
}