Model Factories and Database Seeding
Factories generate realistic fake data for testing and development. Seeders populate your database with initial data.
Creating a Factory
php artisan make:factory PostFactory
class PostFactory extends Factory
{
protected $model = Post::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'category_id' => Category::factory(),
'title' => fake()->sentence(),
'slug' => fake()->unique()->slug(),
'excerpt' => fake()->paragraph(),
'body' => fake()->paragraphs(5, true),
'is_published' => fake()->boolean(80),
'published_at' => fake()->dateTimeBetween('-1 year'),
'views_count' => fake()->numberBetween(0, 10000),
];
}
// Factory states for specific scenarios
public function published(): static
{
return $this->state(fn () => [
'is_published' => true,
'published_at' => fake()->dateTimeBetween('-6 months'),
]);
}
public function draft(): static
{
return $this->state(fn () => [
'is_published' => false,
'published_at' => null,
]);
}
public function featured(): static
{
return $this->state(fn () => [
'is_featured' => true,
]);
}
}
Using Factories
// Single model
$post = Post::factory()->create();
// With state
$post = Post::factory()->published()->featured()->create();
// Multiple models
$posts = Post::factory()->count(50)->published()->create();
// With relationships
$user = User::factory()
->has(Post::factory()->count(10)->published())
->create();
Database Seeders
class DatabaseSeeder extends Seeder
{
public function run(): void
{
// Create admin user
User::factory()->create([
'name' => 'Admin',
'email' => 'admin@example.com',
]);
// Create categories
$categories = Category::factory()->count(8)->create();
// Create users with posts
User::factory()
->count(20)
->has(Post::factory()->count(5)->state(fn () => [
'category_id' => $categories->random()->id,
]))
->create();
}
}
Run with: php artisan db:seed
Factories are essential for testing — they let you create exactly the data your test needs without manual setup.