Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Modern Factories Laravel Package

reedware/laravel-modern-factories

Bring Laravel 8-style class-based model factories to legacy Laravel (5.1–7.x) apps. Write modern PHPUnit-friendly factories today to reduce upgrade pain later, without facades or service providers. Supports PHP 5.5–8.4.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require reedware/laravel-modern-factories
    

    No service provider or facade registration is required.

  2. Define a Factory: Create a factory class in database/factories (or your preferred location) following Laravel 8.x syntax:

    // database/factories/UserFactory.php
    namespace Database\Factories;
    
    use App\Models\User;
    use Illuminate\Database\Eloquent\Factories\Factory;
    
    class UserFactory extends Factory
    {
        protected $model = User::class;
    
        public function definition()
        {
            return [
                'name' => $this->faker->name,
                'email' => $this->faker->unique()->safeEmail,
            ];
        }
    }
    
  3. First Use Case: Use the factory in tests or seeders:

    use App\Models\User;
    use Database\Factories\UserFactory;
    
    $user = UserFactory::new()->create();
    

Where to Look First

  • Laravel 8.x Factory Docs: Eloquent Factories (this package mirrors them).
  • Package Versioning: Check compatibility with your Laravel/PHP version in the README.

Implementation Patterns

Usage Patterns

  1. Stateful Factories: Define custom states for reusable variations:

    public function admin()
    {
        return $this->state([
            'is_admin' => true,
        ]);
    }
    

    Usage:

    $admin = UserFactory::new()->admin()->create();
    
  2. AfterCreating/AfterMaking: Hook into factory lifecycle:

    protected static function newModel()
    {
        return User::new();
    }
    
    public function afterCreating(Model $model)
    {
        $model->update(['verified_at' => now()]);
    }
    
  3. Relationships: Define relationships between factories:

    public function configure()
    {
        return $this->afterCreating(function (User $user) {
            $user->posts()->save(PostFactory::new());
        });
    }
    

Workflows

  1. Test Data Setup: Use factories in DatabaseSeeder or test setups:

    public function run()
    {
        User::factory()->count(10)->create();
    }
    
  2. Mocking APIs: Combine with Faker for realistic test data:

    $user = UserFactory::new()->create([
        'email' => 'test@example.com',
        'password' => bcrypt('password'),
    ]);
    
  3. Legacy Migration Testing: Test database migrations with factory-generated data:

    public function test_migration()
    {
        User::factory()->create();
        $this->artisan('migrate:fresh')->assertExitCode(0);
    }
    

Integration Tips

  • PHP 5.6 or Older: Replace new/for with newFactory/forModel in factory definitions.
  • Custom Faker Providers: Extend Faker\Generator for domain-specific data:
    $factory->afterMaking(function (User $user) {
        $user->apiToken = Str::random(60);
    });
    
  • Laravel Mixins: Use with spatie/laravel-mixins for dynamic factory behavior.

Gotchas and Tips

Pitfalls

  1. Namespace Conflicts: Ensure factories extend Illuminate\Database\Eloquent\Factories\Factory (not Illuminate\Database\Eloquent\ModelFactory). Fix: Explicitly use the modern namespace:

    use Illuminate\Database\Eloquent\Factories\Factory;
    
  2. PHP Version Restrictions:

    • PHP < 7.0: Avoid new/for keywords; use newFactory/forModel.
    • PHP < 7.4: Some Laravel 8 factory features (e.g., afterMaking) may not work. Fix: Check versioning table.
  3. Legacy Eloquent Quirks:

    • has()/for() methods may behave differently in older Laravel. Fix: Test thoroughly and use afterCreating as a fallback.
  4. Autoloading Issues: If factories aren’t autoloaded, manually register the namespace in composer.json:

    "autoload": {
        "psr-4": {
            "Database\\Factories\\": "database/factories"
        }
    }
    

Debugging

  • Factory Not Found: Verify the factory class exists and is autoloaded. Run:

    composer dump-autoload
    
  • Method Not Allowed: For PHP < 7.0, replace:

    $factory->for(User::class); // Error
    

    With:

    $factory->forModel(User::class); // Works
    
  • Faker Issues: Ensure fakerphp/faker is installed and compatible with your PHP version.

Tips

  1. Partial Upgrades: Use the package to modernize factories gradually while keeping the rest of the app on an older Laravel version.

  2. Testing Compatibility: Validate factories work with your Laravel version by running:

    php artisan tinker
    User::factory()->create();
    
  3. Performance: For bulk operations, use create() instead of make() to avoid N+1 queries:

    User::factory()->count(100)->create(); // Efficient
    
  4. Extending Factories: Create a base factory for shared logic:

    class BaseFactory extends Factory
    {
        public function withTimestamps()
        {
            return $this->state([
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }
    }
    
  5. Documentation: Add factory usage examples to your test files for future developers:

    // Example: UserFactory::new()->admin()->withPosts(3)->create();
    
  6. CI/CD Integration: Use factories in CI pipelines to ensure test data consistency:

    # .github/workflows/tests.yml
    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - run: php artisan db:seed --class=TestDatabaseSeeder
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky