LoginSignup
2
3

More than 1 year has passed since last update.

LaravelのテストでCookie::queueを活かす方法

Posted at

前置き

久々に投稿。
LaravelのテストでCookieを扱う際に、やり方が公式でも書いてあるのですが、そもそものやり方が事前にCookieを仕込んでおいてそれを読み取るという方法で、トークンなど動的に変わる値には対応できていません。

要はその、Cookie::queueのテストが避けて通れない場合にどうするか、というのが今回のお題です。

ググっても全然ヒットしなかったので、今回頑張って検証してみました。

使用したバージョン

Laravel ^9.0
PHP ^8.0

公式のやり方

公式

$response = $this->withCookie('color', 'blue')->get('/');

上記を、testCase内に書かないとCookieに書き込まれたことになりません。

対応方法

いきなり答えですが、

protected function saveCookies($cookies, $cookieNames)
{
    $saveNameAndValues = [];
    foreach ($cookies as $cookie) {
        if (in_array($cookie->getName(), $cookieNames, true)) {
            $decryptedString = decrypt($cookie->getValue(), false);
            $arrayCookieValues = explode('|', $decryptedString);
            $saveNameAndValues[$cookie->getName()] = $arrayCookieValues[1];
        }
    }

    if (count($saveNameAndValues) > 0) {
        $this->withCookies($saveNameAndValues);
    }
}

これを

$response = $this->get('/test/hoge');
$response->assertStatus(200);
$this->saveCookies($response->headers->getCookies(), ['fuga', 'buga']);

こう呼び出します。

何をしているかというと

  • ヘッダーのSet-Cookieを取得
  • 暗号化されているので復号
  • その中から平文だけ取得
  • withCookiesでテスト環境のCookieに挿入

です。

これの呼び出し後は、テストするソース内にてCookie::getで取得しているところは正常に値が取得できます。

なお上記のコード内でexplodeしているところは、Laravelのバージョンが変わると仕様も変わる可能性があるので、臨機応変に。

暗号化を無効にしている場合

暗号化を無効化している要素の場合なんですが、withCookiesで値を保存してもなぜか暗号化された状態で保存されてしまいます。

これも検索でヒットしたやり方では上手くいかなかったので、あれこれ試しました。
Laravelのバージョンにもよるのかも。

$this->disableCookieEncryption();

これをテストの1行目に書けば大丈夫です。

なおCookieが暗号化有効のものとそうでないものが混在していたらどうするのか、というところはまだ調べられておりませぬ。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3