In this lesson, let's talk about fake data. Remember the "Product 1" name? So yeah, we shouldn't need to hardcode these values: we can use Eloquent factories to quickly generate fake data for tests.
Let's imagine we want to test pagination. Our table would contain ten records with pagination, and you want to test that pagination works. We will need to create eleven records and test that the last record isn't shown on the first page.
Pagination: Preparing the Code
First, in the Controller, we need to change to use pagination.
app/Http/Controllers/ProductController.php:
class ProductController extends Controller{ public function index(): View { $products = Product::all(); $products = Product::paginate(10); return view('products.index', compact('products')); }}
And the test.
tests/Feature/ProductsTest.php:
use App\Models\Product;use Illuminate\Database\Eloquent\Collection;use Illuminate\Pagination\LengthAwarePaginator;use function Pest\Laravel\get; test('homepage contains empty table', function () { get('/products') ->assertStatus(200) ->assertSee(__('No products found'));}); test('homepage contains non empty table', function () { $product = Product::create([ 'name' => 'Product 1', 'price' => 123, ]); get('/products') ->assertStatus(200) ->assertDontSee(__('No products found')) ->assertSee('Product 1') ->assertViewHas('products', function (LengthAwarePaginator $collection) use ($product) { return $collection->contains($product); });}); test('paginated products table doesnt contain 11th record', function () { for ($i = 1; $i <= 11; $i++) { $product = Product::create([ 'name' => 'Product ' . $i, 'price' => rand(100, 999), ]); } get('/products') ->assertStatus(200) ->assertViewHas('products', function (LengthAwarePaginator $collection) use ($product) { return $collection->doesntContain($product); });});
In this example, we used the PHP for
loop in the test to create eleven records. Then, we go to the /products
URL and assert that the collection doesn't contain the last product. Now, let's run the tests.
The tests are green, but creating the records with the for
loop isn't convenient. Wouldn't it be cool to just quickly generate 11 fake products in one line of code?
Here's where the Factories should be used.
Default Laravel Factory
You can find factories in a database/factories
directory. Laravel skeleton comes with...