Back to Course |
Testing in Laravel 11 For Beginners

Update Product: Test Validation Errors

Now that we have an edit form, let's test that the validation works correctly.


Laravel Code

Again, first, the working code.

php artisan make:request UpdateProductRequest

app/Http/Requests/UpdateProductRequest.php:

use Illuminate\Foundation\Http\FormRequest;
 
class UpdateProductRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
 
public function rules(): array
{
return [
'name' => 'required',
'price' => 'required',
];
}
}

app/Http/Controllers/ProductController.php:

use Illuminate\Http\RedirectResponse;
use App\Http\Requests\UpdateProductRequest;
 
class ProductController extends Controller
{
// ...
 
public function update(UpdateProductRequest $request, Product $product): RedirectResponse
{
$product->update($request->validated());
 
return redirect()->route('products.index');
}
}

The Test

The PUT request is used for updating, so in the test, again acting as an admin, we send a PUT request with empty values.

tests/Feature/ProductsTest.php:

// ...
 
test('product update validation error redirects back to form', function () {
$product = Product::factory()->create();
 
asAdmin()->put('products/' . $product->id, [
'name' => '',
'price' => ''
]);
});

And now, we need to assert. We can first assert that the response is a redirect. And then Laravel has an assertion just for validating errors: assertInvalid.

tests/Feature/ProductsTest.php:

// ...
 
test('product update validation error redirects back to form', function () {
$product = Product::factory()->create();
 
asAdmin()->put('products/' . $product->id, [
'name' => '',
'price' => ''
])
->assertStatus(302)
->assertInvalid(['name', 'price']);
});

Another validation assertion that we can use is assertSessionHasErrors. In the same way as in assertInvalid(), we need to provide keys.

tests/Feature/ProductsTest.php:

// ...
 
test('product update validation error redirects back to form', function () {
$product = Product::factory()->create();
 
asAdmin()->put('products/' . $product->id, [
'name' => '',
'price' => ''
])
->assertStatus(302)
->assertInvalid(['name', 'price'])
->assertSessionHasErrors(['name', 'price']);
});

edit product form validation test


PHPUnit example

Here, we have the same test for PHPUnit.

tests/Feature/ProductsTest.php:

class ProductsTest extends TestCase
{
// ...
 
public function test_product_update_validation_error_redirects_back_to_form()
{
$product = Product::factory()->create();
 
$response = $this->actingAs($this->admin)->put('products/' . $product->id, [
'name' => '',
'price' => ''
]);
 
$response->assertStatus(302);
$response->assertInvalid(['name', 'price']);
$response->assertSessionHasErrors(['name', 'price']);
}
 
private function createUser(bool $isAdmin = false): User
{
return User::factory()->create([
'is_admin' => $isAdmin,
]);
}
}