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?
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
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?
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).Mail::fake(), Queue::fake(), Storage::fake('public'), Event::fake() and then Mail::assertQueued(...).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.