Form Requests

Validate once, test twice

Form requests keep validation out of your controllers. Test them in isolation.

Form Request
// app/Http/Requests/StoreUserRequest.php
class StoreUserRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'unique:users'],
        ];
    }
}
Controller
// app/Http/Controllers/UserController.php
public function store(StoreUserRequest $request)
{
    User::create($request->validated());

    return redirect()->route('users.index');
}
Feature Test — assert form request is used
// tests/Feature/Http/Controllers/UserController/StoreTest.php
$this->post(route('users.store'));

$this->assertContainsFormRequest(StoreUserRequest::class);
Unit Test — assert validation rules
// tests/Unit/Http/Requests/StoreUserRequestTest.php
class StoreUserRequestTest extends TestCase
{
    use TestableFormRequest;

    #[Test]
    public function name_is_required(): void
    {
        $this->createFormRequest(StoreUserRequest::class)
            ->validate(['name' => ''])
            ->assertFails(['name' => 'required']);
    }

    #[Test]
    public function email_must_be_valid(): void
    {
        $this->createFormRequest(StoreUserRequest::class)
            ->validate(['email' => 'not-an-email'])
            ->assertFails(['email' => 'email']);
    }
}

Powered by @jcergolj laravel-form-request-assertions