1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「削除のFeatureTest」を作る手順

Posted at

✅ Step0:前提(準備)

・ 認証は用意済(php artisan make:auth 等)。テストでは actingAs() を使用

・ ルートがある:
    DELETE /tasks/{task} → TaskController@destroy(name('tasks.destroy'))

・ DELETE メソッドを送る: 
    <form action="{{ route('tasks.destroy', ['task' => $task->id]) }}" method="POST">
        @csrf
        @method('DELETE')
        <button type="submit">削除</button>
    </form>

・ 他人のタスクは削除不可:本記事では404で隠す設計

✅ Step1:テストファイル作成

php artisan make:test DeleteTaskTest

→ tests/Feature/DeleteTaskTest.php が作成される

✅ Step2:テストコードを書く

テストコード例

DeleteTaskTest.php
<?php

namespace Tests\Feature;

use App\Models\Task;
use App\Models\TaskCategory;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class DeleteTaskTest extends TestCase
{
    use RefreshDatabase;

    // ----- 自分のタスクを削除できる
    public function test_user_can_delete_own_task()
    {
        // ⓪ 前提:カテゴリ投入
        $this->seed();
        $category = TaskCategory::first();

        // ① ユーザー & タスク作成
        $user = User::factory()->create();
        $task = Task::factory()->create([
            'user_id'          => $user->id,
            'task_category_id' => $category->id,
        ]);

        // ② 認証
        $this->actingAs($user);

        // ③ 削除実行
        $response = $this->delete(route('tasks.destroy', ['task' => $task->id]));

        // ④ レスポンス(今回は削除後にリダイレクトOKか否か)
        $response->assertStatus(302);

        // ⑤ DBから消えていること(物理削除)
        $this->assertDatabaseMissing('tasks', ['id' => $task->id]);
    }

    // ----- 他人のタスクは削除できない
    public function test_user_cannot_delete_others_task()
    {
        // ⓪ 前提:カテゴリ投入
        $this->seed();
        $category = TaskCategory::first();

        // ① ユーザー &.  別ユーザー & タスク作成
        $owner = User::factory()->create();
        $other = User::factory()->create();
        $task = Task::factory()->create([
            'user_id'          => $owner->id,
            'task_category_id' => $category->id,
        ]);

        // ② 認証
        $this->actingAs($other);

        // ③ 削除実行
        $response = $this->delete(route('tasks.destroy', ['task' => $task->id]));

        // ④ 不正アクセスは 404(= assertNotFound)
        $response->assertNotFound();

        // ⑤ まだDBに残っている
        $this->assertDatabaseHas('tasks', ['id' => $task->id]);
    }
}

🧪 RefreshDatabase を使っている場合は テストごとにシーディングが必要

各テストメソッドの前後でDBが初期化されるため、カテゴリ等の初期データは毎回消えます。
よって各テストの冒頭で $this->seed() を実行します。

✅ Step3:TaskFactory(テスト用の初期 Task を楽に作る)

✅ Step3-1:Factoryファイル作成

php artisan make:factory TaskFactory --model=Task

→ database/factories/TaskFactory.php が作成される

✅ Step3-2:TaskFactory の中身を編集

TaskFactory.php
<?php

namespace Database\Factories;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Task>
 */
class TaskFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'user_id'          => User::factory(),
            'title'            => Str::limit($this->faker->sentence(6), 50, ''),
            'task_category_id' => 1,
            'description'      => $this->faker->text,
            'start_at'         => now(),
            'end_at'           => now()->addDay(),
            'is_completed'     => false,
        ];
    }
}

✅ Step4:🌱 TaskCategorySeeder(ID を固定して挿入する理由も含めて)

TaskCategorySeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class TaskCategorySeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $taskCategories = [
            [
                'id'   => 1,
                'name' => '重要 & 緊急',
                'slug' => 'important-urgent'
            ],
            [
                'id'   => 2,
                'name' => '重要',
                'slug' => 'important'
            ],
            [
                'id'   => 3,
                'name' => '緊急',
                'slug' => 'urgent'
            ],
            [
                'id'   => 4,
                'name' => 'その他',
                'slug' => 'other'
            ],
        ];

        foreach($taskCategories as $taskCategory) {
            DB::table('task_categories')->insert([
                'id'   => $taskCategory['id'],
                'name' => $taskCategory['name'],
                'slug' => $taskCategory['slug'],
            ]);
        }
    }
}

✅ Step5:テスト実行

php artisan test

→ ✅ 緑(Passed)になれば成功!

✅ テストをスキップしたい場合

・ 認証系テスト(メール通知必要)など、いまは通らなくてもいいテストを除外したい場合などで使える。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?