laravel Sanctum SPA認証 ログアウト系のテストコードでエラーが発生する（users.remember_tokenを使わないようにする）

# 概要

- laravelにてSanctumでSPA認証を実施してログアウト系のテストコードを実行したところエラーが発生したの解消までの流れを簡単にまとめる。

# エラーまでの経緯

- 下記のようなテストコードを記載した。

    ```test.php
    /**
     * 正常系 ログアウト成功
     *
     * @return void
     */
    public function test_ログアウト成功(): void
    {
        $this->withoutMiddleware(VerifyCsrfToken::class);
        $user = User::factory()->create(['email' => 'test1@example.com']);

        // レスポンスチェック
        $response = $this->actingAs($user)
            ->postJson('/logout');

        $response->assertStatus(200)
            ->assertJson([
                'message' => 'Unauthenticated.'
            ]);

        // ゲスト状態を確認
        $this->assertGuest();
    }
    ```

# エラー

- テストコードを実行したところ500エラーが帰ってきた。
- 下記のように修正してテストを再度走らせて500エラーの内容を確認した。

    ```test.php
    /**
     * 正常系 ログアウト成功
     *
     * @return void
     */
    public function test_ログアウト成功(): void
    {
        $this->withoutMiddleware(VerifyCsrfToken::class);
        $user = User::factory()->create(['email' => 'test1@example.com']);

        // レスポンスチェック
        $response = $this->actingAs($user)
            ->postJson('/logout');
        dd($response);
    //        $response->assertStatus(200)
    //            ->assertJson([
    //                'message' => 'Unauthenticated.'
    //            ]);
    //
    //        // ゲスト状態を確認
    //        $this->assertGuest();
    }
    ```

- 下記のようなエラーが得られた。

    ```
    The attribute [remember_token] either does not exist or was not retrieved for model [App\Models\User].
    ```

- usersテーブルのremember_tokenカラムは使わないので今回マイグレーションから削除している。

# エラー解消までの経緯

- どうやらremember_tokenカラムを削除するだけだと、laravelは「remember_tokenを使わない設定」にならないらしい。
- Userモデルクラスの継承元である`Illuminate\Foundation\Auth\User as Authenticatable`を見てみる。

    ```Illuminate\Foundation\Auth\User.php
    <?php
    
    namespace Illuminate\Foundation\Auth;
    
    use Illuminate\Auth\Authenticatable;
    use Illuminate\Auth\MustVerifyEmail;
    use Illuminate\Auth\Passwords\CanResetPassword;
    use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
    use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
    use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Foundation\Auth\Access\Authorizable;
    
    class User extends Model implements
        AuthenticatableContract,
        AuthorizableContract,
        CanResetPasswordContract
    {
        use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
    }
    ```

- `Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract`のインターフェースの実装を本クラスですることになっており、当該クラスの実装メソッドは`Illuminate\Auth\Authenticatable`のトレイトを呼び出すことで賄っている。
- `Illuminate\Auth\Authenticatable`の関係ありそうなメソッドを見てみる。

    ```Illuminate\Auth\Authenticatable.php
    /**
     * Get the token value for the "remember me" session.
     *
     * @return string|null
     */
    public function getRememberToken()
    {
        if (! empty($this->getRememberTokenName())) {
            return (string) $this->{$this->getRememberTokenName()};
        }
    }

    /**
     * Set the token value for the "remember me" session.
     *
     * @param  string  $value
     * @return void
     */
    public function setRememberToken($value)
    {
        if (! empty($this->getRememberTokenName())) {
            $this->{$this->getRememberTokenName()} = $value;
        }
    }

    /**
     * Get the column name for the "remember me" token.
     *
     * @return string
     */
    public function getRememberTokenName()
    {
        return $this->rememberTokenName;
    }
    ```

- 上記のメソッドたちをUserモデルクラスでオーバーライドして使わないようにする。

    ```User.php
    /**
     * Get the remember token value.
     *
     * @return string|null
     */
    public function getRememberToken(): string|null
    {
        return null;
    }

    /**
     * Set the remember token value.
     *
     * @param  string  $value
     * @return void
     */
    public function setRememberToken($value): void
    {
        // Do nothing.
    }

    /**
     * Get the name of the remember token.
     *
     * @return string
     */
    public function getRememberTokenName(): string
    {
        return '';
    }
    ```

- テストを走らせると200が返るようになった。