Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-06-18

下記のような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'));
    }
}
5
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
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?