Laravelでテストを記述する際、「ユーザーの認証状態を指定しなくてはならない場面」が出てきます。
例えば、こんな感じでコントローラー側でユーザの認証状態によってviewに渡すデータを切り替えている場合です。
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
class ExampleController extends Controller
{
public function index()
{
if (!Auth::check()) {
$data = "ログインしていません";
}
if (Auth::check()) {
$data = "ログインしています";
}
return view('welcome',['data' => $data]);
}
}
こういった場合、テスト側でユーザーの認証状態を指定する必要があります。
では、どうすればテスト側でユーザーの認証状態を指定できるのでしょうか?
様々な手法があるとは思いますが、今回は以下の二つを紹介します。
- actingAsヘルパメソッドを利用する
- Authファサードをモックする
actingAsヘルパメソッドを利用する
一つ目は、Laravelが提供しているactingAsヘルパメソッドを利用する方法です。
利用例はこちら。
<?php
use App\User;
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = factory(User::class)->create();
$response = $this->actingAs($user)
->withSession(['foo' => 'bar'])
->get('/');
}
}
まずはファクトリ等を使ってテスト用のユーザーデータを作ります。
その後に、actingAsヘルパを使うことで、ユーザーをログイン状態にすることができます。
使い方はシンプルですね。
実際にactingAsを使って書いたテスト例は以下の記事に書かれてあるので、ぜひ参考にしてみて下さい。
Authファサードをモックする
もう一つはAuthファサードをモックする方法です。
まずは、「モックとは何か」を簡単に説明します。
こちらの記事に良い感じの説明がありました。
Mockとは、簡単に言うとクラスの動作をシミュレートするためのオブジェクトです。 テスト対象クラスが呼び出している(=依存している)クラスをMockで差し替え、Mockの動作内容を定義することで、望むテスト条件を容易に作ることができます。
要は、指定したクラスが実行するメソッドの動作をテストの条件に合わせて事前に決めてしまうということです。
例えば今回の場合だと、Authファサードのcheckメソッドの動作を事前に指定することで、任意の認証状態を作ることができます。
このモックの仕組みを使って、実際に最初に紹介したコントローラのテストを書いてみましょう。
<?php
namespace Tests\Feature;
use Illuminate\Support\Facades\Auth;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/** @test */
public function ログインしていない場合のテスト()
{
Auth::shouldReceive('check')->andReturn(false);
$response = $this->get('/');
$response->assertViewHas('data', 'ログインしていません');
}
/** @test */
public function ログインしている場合のテスト()
{
Auth::shouldReceive('check')->andReturn(true);
$response = $this->get('/');
$response->assertViewHas('data', 'ログインしています');
}
}
まずshouldReceiveメソッドに対してcheckメソッドを指定し、次にandReturnに返り値を指定します。
checkの場合は返り値がBooleanなので今回はtrue(false)を指定しました。
以上により、 Auth::check()の際の動作をモックに差し替えることができました。
実際にテストを実行してみましょう。
二つとも通っていることが確認できます。
おわりに
今回はLaravelでテストを実行する際にユーザーの認証状態を指定する方法として、以下の二つを紹介しました。
- actingAsヘルパメソッドを利用する
- Authファサードをモックする
これらの方法がベストプラクティスではないとは思いますが、一つの選択肢として参考にして頂けると嬉しいです。
