LoginSignup
0
0

More than 1 year has passed since last update.

CakePHP4でログイン認証のテストする時にセッションの取得できなくてハマった

Last updated at Posted at 2021-06-28

CakePHP4でログイン認証のテストを書こうとした時に、セッションが取得できなくてハマったのでメモ

やりたかったこと(失敗コード)

UsersController

    public function login()
    {
        $this->request->allowMethod(['get', 'post']);
        $result = $this->Authentication->getResult();

        // 認証成功
        if ($result->isValid()) {
            $target = $this->Authentication->getLoginRedirect() ?? '/';
            return $this->redirect($target);
        }
        // ログインできなかった場合
        if ($this->request->is('post') && !$result->isValid()) {
            $this->Flash->error('ログインIDかパスワードが間違っています');
        }
    }

UsersControllerTest

    public function testLoginOk(): void
    {
        $this->enableCsrfToken();   // CSRFトークン生成

        $this->post('/users/login', [
            'username' => 'misato', // idが2のユーザー
            'password' => 'misato',
        ]);

        // セッションのユーザーidが2であることを確認
        $this->assertSession(2, 'Auth.User.id');
    }
}

テスト結果

セッションが見つからなくて、失敗する

There was 1 failure:

1) App\Test\TestCase\Controller\UsersControllerTest::testLoginOk
Failed asserting that 2 is in session path 'Auth.User.id'.

【改善案】 テストコードは$_SESSIONを使う

UsersControllerTest

    public function testLoginOk(): void
    {
        $this->enableCsrfToken();   // CSRFトークン生成

        $this->post('/users/login', [
            'username' => 'misato',
            'password' => 'misato',
        ]);

        $this->assertEquals(2, $_SESSION['Auth']->id);
    }

これなら、テスト通る!!

OK (1 test, 1 assertion)

【おまけ】PHPUnitはリクエストごとにセッションがリセットされる

PHPUnitは同じテストメソッド内でも、リクエストごとにセッションがリセットされる仕様のようです。
そのため、セッションを引き継ぎたいときは、明示的にセッションを引き継がせる必要があります。

具体的には以下のような感じです

UsersController

    public function home()
    {
        $session = $this->getRequest()->getSession();

        if (empty($session->read('works'))) {
            $session->write('works', 'on');
        } else {
            $session->write('works', 'off');
        }
    }

UsersControllerTest

    public function testHome(): void
    {
        $this->get('/');
        $this->assertSession('on', 'works'); //ここは成功します。

        $this->session($_SESSION); // セッションを引き継ぐ

        $this->get('/');
        $this->assertSession('off', 'works'); //セッションを引き継がないと、ここで失敗
    }

参考

0
0
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
0
0