Laravel5.5でのテストでミドルウェアを...

GLUGの熊谷です。
弊社で作成しているサービスでは、PHP7とフレームワークにLaravel5.5を採用しています。

Laravelの便利機能の一つに、ミドルウェアがあります。
ルーティングに組み込めば管理も便利になったりするのですが、便利だからこそうっかり自動テストでハマったりします。
Featureテストではミドルウェアが原因で期待値と違った結果になる事も。それに気づかずに、テスト対象のコードを追いかけたり、テストコード自体を追いかけたり。
それなので、テストの場合のみミドルウェアを無効にしたりした方が良い場合があります。

ミドルウェアが有効になっているかのテストと、ミドルウェアを一時無効にして行うテストのサンプルを掲載します。
サンプルのテスト対象の事前条件は下記になります。

// テスト対象のルーティング設定
Route::view('/', 'index')->middleware('my_middleware');

ミドルウェアが有効か判定

<?php
namespace Tests\Feature;

use Tests\TestCase;

/**
 * ミドルウェアが有効かテストするサンプル
 *
 */
class SampleWithMiddlewareTest extends TestCase
{
    public function testSample()
    {
        $this->get('/');
        $this->assertContains('my_middleware', \Route::current()->middleware(), 'my_middlewareが有効である');
    }
}
  • \Route::current() で直前に実行されたHTTPテストのルーティング情報が取得できる
  • \Route::current()->middleware() 取得できたルーティング情報からミドルウェア情報が取得できる
    • $this->assertMiddleware() の様な標準メソッドはないのだろうか・・・
  • 取得できたミドルウェア情報に期待値が含まれているか検証する

ミドルウェアを一時無効にしてテストを実行する

<?php
namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

/**
 * 特定のミドルウェアを無効にしてテスト実行サンプル
 *
 */
class SampleWithoutMiddlewareTest extends TestCase
{
    use WithoutMiddleware;

    public function testSample()
    {
        $this->withoutMiddleware(\App\Http\Middlewae\MyMiddleware::class);

        // テストさせたい内容をこれ以降に実装(サンプルとして200ステータス検証)
        $this->get('/')->assertSuccessful();
    }
}
  • \Illuminate\Foundation\Testing\WithoutMiddleware トレイトの withoutMiddleware() を実行する
  • withoutMilldeware() でミドルウェアを無効にした後にテストを実装