So far, we have been testing the getting of the data. So now, let's test if data exists in the database.
First, let's create a simple form and store the product in the database.
We will use Form Request for the validation.
php artisan make:request StoreProductRequest
app/Http/Requests/StoreProductRequest.php:
class StoreProductRequest extends FormRequest{ public function rules(): array { return [ 'name' => 'required', 'price' => 'required', ]; } public function authorize(): bool { return true; }}
app/Http/Controllers/ProductController.php:
use App\Models\Product;use Illuminate\Contracts\View\View;use Illuminate\Http\RedirectResponse;use App\Http\Requests\StoreProductRequest; class ProductController extends Controller{ // ... public function create(): View { return view('products.create'); } public function store(StoreProductRequest $request): RedirectResponse { Product::create($request->validated()); return redirect()->route('products.index'); }}
resources/views/products/create.blade.php:
<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> {{ __('Create product') }} </h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div class="overflow-hidden overflow-x-auto p-6 bg-white border-b border-gray-200"> <div class="min-w-full align-middle"> <form method="POST" action="{{ route('products.store') }}"> @csrf <div> <x-input-label for="name" :value="__('Name')" /> <x-text-input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus /> <x-input-error :messages="$errors->get('name')" class="mt-2" /> </div> <div class="mt-4"> <x-input-label for="price" :value="__('Price')" /> <x-text-input id="price" class="block mt-1 w-full" type="text" name="price" :value="old('price')" required /> <x-input-error :messages="$errors->get('price')" class="mt-2" /> </div> <div class="flex items-center mt-4"> <x-primary-button> {{ __('Save') }} </x-primary-button> </div> </form> </div> </div> </div> </div> </div></x-app-layout>
After visiting the create product, we see a form and can save a new product.
Now let's add tests that the creation of the product works and the record is found in the database.
In the test, first, we make a POST request acting as an admin user and passing product values as an array. Then, from the response, we assert that the user is redirected and redirected to the correct page.
Then, we make a database assertion to check if the database has the product we just created in the products
table.
Finally, we check if the last product has the same name and price we specified when creating a new product.
tests/Feature/ProductsTest.php:
class ProductsTest extends TestCase{ use RefreshDatabase; // ... public function test_create_product_successful() { $product = [ 'name' => 'Product 123', 'price' => 1234 ]; $response = $this->actingAs($this->admin)->post('/products', $product); $response->assertStatus(302); $response->assertRedirect('products'); $this->assertDatabaseHas('products', $product); $lastProduct = Product::latest()->first(); $this->assertEquals($product['name'], $lastProduct->name); $this->assertEquals($product['price'], $lastProduct->price); } private function createUser(bool $isAdmin = false): User { return User::factory()->create([ 'is_admin' => $isAdmin, ]); }}
In this test, we test the same scenario of product creation, but inside, we check a few things: