Factories
Overview
Factories generate fake model instances for testing and development. Sutomo uses Laravel's Eloquent Factory pattern, organized by domain. Each factory defines sensible defaults using Faker — making it easy to create realistic test data with minimal boilerplate.
Factories are used in:
- Tests — via
Model::factory()->create()orModel::factory()->make() - Dummy seeders —
DummySeed.phpcalls factories to populate development environments - Feature demos — Quick data generation for UI previews
Folder Structure
database/factories/
├── UserFactory.php # Top-level user factory
├── ContactFactory.php # Contact factory
├── Academic/ # Academic domain
│ ├── AnnouncementFactory.php
│ └── ...
├── Administration/ # Administration
│ └── ...
├── Educator/ # Educator domain
│ └── TeacherFactory.php
├── Geographic/ # Geographic domain
│ └── ...
├── Institution/ # Institution domain
│ └── SchoolFactory.php
├── LeaveManagement/ # Leave management
│ └── ...
├── Platform/ # Platform factories
│ ├── Approval/
│ ├── Bulletin/
│ ├── ContactMessage/
│ ├── DocumentType/
│ ├── Employee/
│ ├── Gender/
│ ├── Onboarding/
│ ├── Pipeline/
│ ├── Rating/
│ ├── Stage/
│ └── Template/
├── Recruitment/ # Hiring/Recruitment
│ ├── ApplicantFactory.php
│ ├── CandidateEducationFactory.php
│ ├── CandidateExperienceFactory.php
│ ├── CandidateFactory.php
│ ├── VacancyFactory.php
│ └── VacancyStateFactory.php
└── Support/
└── ...Patterns
1. Standard Factory
Each factory maps to a single model and defines default attribute values:
php
class SchoolFactory extends Factory
{
protected $model = School::class;
public function definition(): array
{
return [
'code' => $this->faker->unique()->word(),
'name' => $this->faker->company(),
'country_code' => $this->faker->countryCode(),
'address' => $this->faker->address(),
];
}
}2. UserFactory with Shared Password
The UserFactory stores a shared password hash so all generated users use the same password — useful for testing login:
php
class UserFactory extends Factory
{
protected static ?string $password;
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'password' => static::$password ??= Hash::make('password'),
// ...
];
}
public function unverified(): static
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}3. Custom States
Use factory states for variations:
php
// Without calling unverified(), user is verified
$user = User::factory()->create();
// Unverified user for email verification tests
$user = User::factory()->unverified()->create();4. Domain Organization
Factories are nested by domain matching the model namespace. For example, CandidateFactory.php lives in database/factories/Recruitment/ matching App\Models\Recruitment\Candidate\Candidate:
php
namespace Database\Factories\Recruitment;
use App\Models\Recruitment\Candidate\Candidate;
class CandidateFactory extends Factory
{
protected $model = Candidate::class;
// ...
}5. Using Factories in Seeders
php
class DummySeed extends Seeder
{
public function run(): void
{
// Create 1 school with 10 teachers and 100 students
$school = School::factory()->create();
Teacher::factory()->count(10)->create(['school_id' => $school->id]);
Student::factory()->count(100)->create(['school_id' => $school->id]);
}
}Key Files
database/factories/
├── UserFactory.php # User model — shared password, unverified state
├── ContactFactory.php # Contact model
├── Institution/SchoolFactory.php # School with default location data
├── Recruitment/
│ ├── CandidateFactory.php # Job candidate
│ ├── CandidateEducationFactory.php # Candidate education history
│ ├── CandidateExperienceFactory.php # Candidate work experience
│ ├── ApplicantFactory.php # Job applicant
│ ├── VacancyFactory.php # Job vacancy
│ └── VacancyStateFactory.php # Vacancy workflow state
├── Platform/
│ ├── Gender/GenderFactory.php # Gender reference
│ ├── Employee/EmployeeFactory.php # Employee records
│ ├── Approval/ApprovalFactory.php # Approval workflows
│ ├── Pipeline/PipelineFactory.php # Hiring/contract pipelines
│ ├── Stage/StageFactory.php # Pipeline stages
│ ├── Template/TemplateFactory.php # Message templates
│ ├── Rating/RatingFactory.php # Platform ratings
│ ├── Bulletin/BulletinFactory.php # Bulletins
│ ├── Onboarding/OnboardingFactory.php # Onboarding items
│ └── DocumentType/DocumentTypeFactory.php # Document types
├── Educator/
│ └── TeacherFactory.php # Teacher records
├── Academic/
│ └── AnnouncementFactory.php # Academic announcements
└── LeaveManagement/
└── ...