Laravel

Lesson 10

Feature tests with database assertions

Write Laravel feature tests that hit the HTTP boundary and assert the database state that matters.

Good Code

tests/Feature/CreateReviewTest.php
<?php

namespace Tests\Feature;

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

final class CreateReviewTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_create_review(): void
    {
        // The test proves the HTTP endpoint writes the expected review row.
        $user = User::factory()->create();

        $this->actingAs($user)
            ->postJson('/reviews', ['title' => 'Practical Laravel', 'body' => 'Clear examples help reviewers.', 'rating' => 5])
            ->assertCreated();

        $this->assertDatabaseHas('reviews', ['user_id' => $user->id, 'title' => 'Practical Laravel']);
    }
}

Bad Code

tests/Feature/CreateReviewTest.php
<?php

public function test_create_review(): void
{
    // A status-only test misses whether the review was saved correctly.
    $this->post('/reviews', [
        'title' => 'Practical Laravel',
        'body' => 'Clear examples help reviewers.',
    ])->assertOk();
}

Review Notes

What to review

Good Code

The good version exercises the HTTP endpoint, authenticates a user, and asserts the database row that should exist after the request.

Bad Code

The bad version only checks a status code. It could pass while the endpoint silently drops fields or writes the wrong owner.

Takeaways

  • A useful feature test proves both the HTTP result and the persistent behavior users depend on.