zero-to-prod/data-model-factory

Factory for Instantiating a Class

v71.1.6 2024-10-23 18:00 UTC

This package is auto-updated.

Last update: 2024-10-23 18:01:26 UTC


README

Repo GitHub Actions Workflow Status Packagist Downloads Packagist Version GitHub repo size License

Installation

Install the package via Composer:

composer require zero-to-prod/data-model-factory

For easier model instantiation, we recommend adding the DataModel trait.

Additional Packages

Usage

This example makes use of the DataModel trait to instantiate the User class.

You can install the DataModel package like this:

composer require zero-to-prod/data-model

If you don't want to use this trait, you can customize the class instantiation this way.

  1. Include the Factory trait in your factory class.
  2. Set the $model property to the class you want to instantiate.
  3. Implement a definition() method that returns an array of default values.
class User
{
    use \Zerotoprod\DataModelFactory\DataModel;

    public $first_name;
    public $last_name;
    
    public static function factory(array $states = []): UserFactory
    {
        return new UserFactory($states);
    }
}

class UserFactory
{
    use \Zerotoprod\DataModelFactory\Factory;

    protected $model = User::class;

    protected function definition(): array
    {
        return [
            'first_name' => 'John',
            'last_name' => 'N/A'
        ];
    }
    
    public function setFirstName(string $value): self
    {
        return $this->state(['first_name' => $value]);
    }
    
    public function setLastName(): self
    {
        return $this->state(function ($context) {
            return ['first_name' => $context['last_name']];
        });
    }
    
    public function make(): User
    {
        return $this->instantiate();
    }
}

$User = User::factory([User::last_name => 'Doe'])
            ->setFirstName('Jane')
            ->make();
// UserFactory::factory([User::last_name => 'Doe'])->make(); Also works

echo $User->first_name; // 'Jane'
echo $User->last_name;  // 'Doe'

Custom Class Instantiation

To customize instantiation, override the make() method.

class User
{
    public function __construct(public string $fist_name, public string $last_name)
    {
    }
}

class UserFactory
{
    use \Zerotoprod\DataModelFactory\Factory;

    private function definition(): array
    {
        return [
            'first_name' => 'John',
            'last_name' => 'Doe',
        ];
    }

    private function make(): User
    {
        return new User($this->context['first_name'], $this->context['last_name']);
    }
}

$User = UserFactory::factory()->make();

echo $User->first_name; // 'Jane'
echo $User->last_name;  // 'Doe'