Help us understand the problem. What is going on with this article?

【Laravel】 MiddlewareのUnit Testで、テストスイート毎に使い捨てのSessionを使う

下記のようなMiddlewareのクラスがあったとします。
リクエストで渡ってきたパラメータの tokenの値を、sessionの中に入れるMiddlewareです。

TokenToSession.php
<?php
namespace App\Http\Middleware;

use Closure;

class TokenToSession
{
    public function handle($request, Closure $next)
    {
        if (!is_null($request->input('token'))) {
            $request->session()->put('token', $request->input('token'));
        }

        return $next($request);
    }
}

検証したいこと

そのため、このメソッドをテストするとしたら、

  • リクエストパラメータに token が入ってきたら、セッションの token にトークンが入る
  • リクエストパラメータに token が入ってこなければ、セッションの token に値が存在しない

のテストスイートを書くことになるでしょう。

セッションのチェック方法

セッションはモック化させるでも良いのですが、ここは「セッションのフリをして、putが呼ばれたら何かしらの場所に実際にtokenを保存してくれるもの」があると便利です。

こういった場合に便利なのが、Laravelで提供されている NullSessionHandler を使います。
NullSessionHandler は、セッションの永続化をしないハンドラーです。
他には FileSessionHandler などがあります。

requestオブジェクトがhandler の引数に入ってくるので、モック化させたrequestの中に、NullSessionHandlerを使って生成したセッションオブジェクトを入れてあげれば良さそうです。

テスト実装

TokenToSessionTest.php
<?php

namespace Tests\Unit;

use Tests\TestCase;
use Mockery;
use Illuminate\Session\Store;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\Request;
use Illuminate\Session\NullSessionHandler;
use App\Http\Middleware\TokenToSession;

class TokenToSessionTest extends TestCase
{
    public function setUp()
    {
        parent::setUp()

        // どちらのテストスイートでも必ずセッションを使うので、setUp内でセッションオブジェクトを生成する
        $session_handler = new NullSessionHandler();
        $this->session = new Store('test', $session_handler);
    }

    // GETパラメータにtokenが入っている時は、セッションにtokenが保存される
    public function testHandleTokenIsInSessionWhenTokenIsInGetParams()
    {
        $token = 'dummy_token';

        // requestオブジェクトをモック化
        $request = Mockery::mock(Request::class);

        // $request->input('token') が dummy_token を常に返す
        $request->shouldReceive('input')
                ->with('token')
                ->andReturn($token);

        // $request->session() が setUpで生成したセッションオブジェクトを常に返す
        $request->shouldReceive('session')
                ->andReturn($this->session);

        // action
        $middleware = new TokenToSession();
        $middleware->handle($request, function () {
        });

        // sessionオブジェクトの token の中に、 dummy_tokenが入っている
        $this->assertEquals($token, $this->session->get('token'));
    }

    // GETパラメータにtokenが入っていない時は、セッションにtokenが入らない
    public function testHandleTokenIsNullSessionWhenTokenIsNotInGetParams()
    {
        $request = Mockery::mock(Request::class);

        // $request->input('token') が 何も返さない
        $request->shouldReceive('input')
                ->with('token')
                ->andReturn(null);

        $request->shouldReceive('session')
                ->andReturn($this->session);

        // action
        $middleware = new TokenToSession();
        $middleware->handle($request, function () {
        });

        // sessionオブジェクトの中には token が存在しない
        $this->assertFalse($this->session->has('token'));
    }
}
Canon11
OMO事業のベンチャー企業でバックエンドやってます。 帰り道で音ゲーやりがち。 メモがメインです。 Django / AWS / GCP / Docker / CircleCI / Terraform / php
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした