LaravelのUnitTestで、ルートのテストをする際に、ログインをしようとして302エラーになったときは、CSRF対策が効いていることが多いです。
もし、以下のようなソースコードを書いた初回にエラーが発生してこの記事を見ている場合は、UnitTestの実行時にCSRFをオフにするように設定すると回避できると思います。
以下、サンプルコードです。
<?php
namespace Tests\Feature\Admin;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use DB;
class UserControllerTest extends TestCase
{
use RefreshDatabase;
/**
* マイページ表示
*
* @return void
*/
public function testMypage()
{
$this->seed();
// ログイン画面
$response = $this->get(route('user.login'));
$response->assertStatus(200);
// ログイン認証
$response = $this->post(route('user.login.post'), ['username' => 'aaaa', 'password' => 'apass']);
$response->assertRedirect(route('mypage')); //ログインが成功してmypageに遷移したことをチェック
// ~~以下略~~
このようなテストを行ったときに、リダイレクト先がlogoutだったり、login画面だったりと、意図しないリダイレクト先の場合は、CSRF対策をオフにします。
laravel\app\Http\Middleware\VerifyCsrfToken.php
を以下のように変更します。
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
];
public function handle($request, \Closure $next)
{
if(env('APP_ENV') !== 'testing')
{
return parent::handle($request, $next);
}
return $next($request);
}
}
もう1点、laravel\phpunit.xml
の <server name="APP_ENV" value="testing"/>
に変更します。
このとき、laravel\.env.testing
ファイルが必要です。
laravel\.env.testing
ファイルは、基本的には .env
のコピーでOKなのですが、できれば UnitTest 実行時専用のデータベースがあると、 php artisan test
実行時にデータベースのデータが毎回リフレッシュされてしまうようなことがないので、便利です。
開発環境の構築を担当している方に、Dockerでテスト用のデータベースを準備してほしいと依頼してみると良いと思います。