在功能测试中,我们通常要使用 $this->postJson() 系列方法来测试接口,在此之前只要用 $this->actingAs() 即可解决登录态的问题
不过这次要测的接口比较特别,需要往 cookie 中塞 token 来维持登录态

我简单看了一下 postJson() 的源码,第三个参数名叫 $header。噢,我明白了,这还不简单?于是我:

$header = ['Set-Cookie: token=abc123'];

结果不行,那我换成

$header = ['Set-Cookie' => 'token=abc123'];

还是不行。只能进一步阅读源码,在 Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:522 看到如下代码:

return $this->call(
    $method,
    $uri,
    [],
    $this->prepareCookiesForJsonRequest(),
    $files,
    $this->transformHeadersToServerVars($headers),
    $content
);

倒数第二个参数引起了我的注意,transformHeadersToServerVars()?原来 $header 最终会被转换为 $_SERVER 里的数据,这样的话用它来传递 cookie 是行不通了
这时我又注意到第四个参数 prepareCookiesForJsonRequest(),跟踪进去一看,这个方法会判断属性 $this->withCredentials 是否为 true,如果不是则返回空数组。而这个属性默认是 false
继续跟踪,发现 withCredentials() 方法可以将这个属性设为 true

传递 cookie 的问题是解决了,不过 cookie 该如何设定呢?来都来了,我直接在这个类里搜索 cookie 关键词,很快就看到了 withUnencryptedCookie() 方法。这个项目并没有使用 Laravel 自带的 cookie 加密功能,那么就决定是它了
最后一试,果然实现了我想要的效果