DEV3 Technologies home

DEV3 Developer Forum

How do I write a Laravel 12 feature test for an authenticated route?

Laravel helpSolved0 views
dev3 ·

I want to test that only logged in users can create posts and that validation errors show up. I am not sure about RefreshDatabase, factories and actingAs. Can someone show a complete example for Laravel 12?

#laravel#testing#phpunit

0

1 reply

dev3 · Accepted answer

Here is a complete feature test using Pest-free PHPUnit syntax (Pest works the same with different wrappers).

namespace Tests\Feature;

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

class CreatePostTest extends TestCase
{
    use RefreshDatabase;

    public function test_guest_is_redirected_to_login(): void
    {
        $this->post('/posts', ['title' => 'Hi'])->assertRedirect('/login');
        $this->assertDatabaseCount('posts', 0);
    }

    public function test_user_can_create_post(): void
    {
        $user = User::factory()->create();

        $this->actingAs($user)
            ->post('/posts', ['title' => 'Hello', 'body' => 'World'])
            ->assertRedirect('/posts');

        $this->assertDatabaseHas('posts', ['title' => 'Hello', 'user_id' => $user->id]);
    }

    public function test_title_is_required(): void
    {
        $this->actingAs(User::factory()->create())
            ->post('/posts', ['body' => 'x'])
            ->assertSessionHasErrors('title');
    }
}

For JSON APIs

$this->actingAs($user, 'sanctum')
    ->postJson('/api/posts', ['title' => ''])
    ->assertUnprocessable()
    ->assertJsonValidationErrors(['title']);

or Sanctum::actingAs($user, ['posts:write']).

Key points

  • RefreshDatabase migrates once and wraps each test in a transaction. Use an in-memory SQLite or a dedicated test database in phpunit.xml (never your dev DB).
  • Use factories for data, not hand-written inserts.
  • Fake side effects: Mail::fake(), Queue::fake(), Storage::fake('public'), Event::fake() and then Mail::assertQueued(...).
  • Run with php artisan test --filter=CreatePostTest. Add --parallel for speed.
  • withoutExceptionHandling() helps while debugging a failing test because you see the real exception instead of a 500 page.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.