LaravelでPHPUnitを使って、CRUD処理のテストを自動化させる方法を解説しています。
今回は、投稿の削除の処理のテストを書いていきます。投稿の削除は、投稿者本人と管理者のみが行えるようにします。
実際の開発の現場でも使えるよう、実践的なテストの作り方をご紹介していきますね。
Webアプリの前提条件
Webアプリの前提条件や事前準備については、前回までの記事にて解説しています。
新規作成画面の表示と保存、編集、更新のテスト方法も解説しています。
PHPUnitの基本的な使い方を知りたい場合は、まずは下記記事をご覧ください。
事前準備:Gate(ゲート)の設定
今回は、投稿の削除は、投稿者本人と管理者のみが行えるものとします。
管理者かどうかは、usersテーブルのroleカラムに”admin”と入っているかどうかで判断するようにします。
この前提で、app/Providers/AuthServiceProvidersに、次のようにadminゲートを作っておきましょう。
【app/Providers/AuthServiceProviders】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; (省略) public function boot(): void { Gate::define('admin', function ($user, $post) { if(($user->id==$post->user_id) || ($user->role=='admin')) { return true; } return false; }); } |
このゲートを使うと、投稿者本人($user->id==$post->user_id))またはユーザーの役割がadmin($user->role==’admin’)であれば、return true として、処理を実行します。
コントローラの投稿の編集画面表示と更新のメソッドには、下記のように作成したadminゲートを設定しておきます。
【PostController】
1 2 3 4 5 6 |
public function destroy(Request $request,Post $post) { $this->authorize('admin', $post); (省略) } |
CRUD処理のテスト:投稿の削除
投稿の削除のテストを作っていきましょう。
tests/Feature/PostTest.phpを開き、下記のようにコードを加えます。
【tests/Feature/PostTest.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// 投稿の削除テスト(投稿者本人または管理人のみ削除できる) public function test_can_delete_post() { $user = User::factory()->create(); $post = Post::factory()->create(['user_id' => $user->id]); $response = $this->actingAs($user)->delete('/post/' . $post->id); $response->assertStatus(302); $this->assertDatabaseMissing('posts', ['id' => $post->id]); // 別のユーザーが投稿を削除しようとした場合に403エラーになることを確認 $anotherUser = User::factory()->create(); $post2 = Post::factory()->create(['user_id' => $anotherUser->id]); $post2->save(); $response = $this->actingAs($user)->delete('/post/' . $post2->id); $response->assertStatus(403); // 管理者が投稿を削除できることを確認 $adminUser = User::factory()->create(['role' => 'admin']); $post3 = Post::factory()->create(['user_id' => $user->id]); $response = $this->actingAs($adminUser)->delete('/post/' . $post3->id); $response->assertStatus(302); $this->assertDatabaseMissing('posts', ['id' => $post3->id]); } |
コードの意味を解説します。
- factoryを使って新規ユーザー($user)と新規投稿($post)を作成します。$postのuser_idは、$userのidとします。
- このユーザーとして、投稿を削除します。その後、HTTPステータスが302であるかどうかを確認します。HTTPステータスが302であれば、リクエストが指定したURLにリダイレクトされた状態ということになります。また、$this->assertDatabaseMissingによって、
$postのデータがデータベースから削除されていることも確認します。 - 次に、もう一人ダミーユーザー($anotherUser)を作成します。新たに投稿($post2)を作成します。$post2のuser_idは、$anotherUserのidとします。
- この状態で、最初のuserが投稿($post2) を削除しようとします。ですが、$post2のuser_idは、anotherUserのidであるため、削除できません。この時、HTTPステータスが403であるかどうかを確認します。HTTPステータスが403は、権限がないということになります。
- 次に、管理者権限を持つダミーユーザー($adminUser)を作成します。新規投稿($post3)も作成します。$post3のuser_idは、$userのidとします。
- この状態で、$adminUserが投稿($post3) を削除します。その後、HTTPステータスが302であるかどうかを確認します。HTTPステータスが302であれば、リクエストが指定したURLにリダイレクトされた状態ということになります。また、$this->assertDatabaseMissingによって、$post2のデータがデータベースから削除されていることも確認します。
これによって、自分が作った投稿を削除できるかテストしています。また、自分以外の人が作成した投稿を削除しようとすると、403エラーになるかどうかをテストしています。さらに、管理者であれば自分以外の人が作成した投稿を削除できるかテストしています。
コードを保存したら、下記コマンドを実行します。
1 |
php artisan test |
無事にテスト通りに進んだ場合には、下記のように返ってきます。
データベースを確認すると、ユーザーが3人と投稿が1つ登録されています。確認してみてください。
さいごに
投稿の削除のテスト記述方法を解説しました。
また今回までで4回にわたり、LaravelでPHPUnitのテストを作るための方法をお伝えしてきました。
テストを書くのは正直メンドウですが、ただ一度書いてしまえば、時間が取られるテスト作業を自動化できます。
今後のWebアプリ開発を便利にするために、テストの自動化、よかったら試してみてくださいね。
なおテストではFactoryやSeederといったダミーデータの作成も重要になります。他のブログ記事でも解説しています。
また執筆した書籍「Laravelの教科書」の後半でも、ダミーデータの作り方を解説しています。
ご興味あれば、見てみてください。こちらのページでも、書籍についてご紹介しています。