insolita / yii2-muffin-factory
Port of laravel factory
Installs: 30 362
Dependents: 1
Suggesters: 0
Security: 0
Stars: 9
Watchers: 3
Forks: 3
Open Issues: 0
Type:yii2-extension
Requires
- php: >=7.2
- fakerphp/faker: ~1.9|~1.10
- yiisoft/yii2: >=2.0.14
Requires (Dev)
- codeception/specify: ~1.0
- codeception/verify: ~1.0.0
- phpunit/phpunit: ~6.0|~7.0|~8.0|~9.0
This package is auto-updated.
Last update: 2024-12-19 03:46:58 UTC
README
A Port of laravel factory for generate fixtures on fly and database seeding
Installation
Either run
composer require -dev insolita/yii2-muffin-factory:~2.0.0
or add
"insolita/yii2-muffin-factory": "~2.0.0"
in require-dev section of your composer.json
file.
Configure
Add in bootstrap for test suite (or in every app, where it can be used)
//with default factory path by alias @tests/factories Yii::$container->setSingleton( \insolita\muffin\Factory::class, [], [\Faker\Factory::create('en_EN')] ); //with custom factory path Yii::$container->setSingleton( \insolita\muffin\Factory::class, [], [ \Faker\Factory::create('ru_RU'), //Faker language '@common/data/factories' // Custom directory for factories ] );
Create Factories
You can create all factories in single file, or in individual files in directory defined in factory configuration
example UserFactory.php
/** * @var \insolita\muffin\Factory $factory **/ $factory->define(User::class, function (\Faker\Generator $faker) { static $password; return [ 'name' => $faker->name, 'lastName' => $faker->name, 'email' => $faker->unique()->safeEmail, 'status'=>'default', 'passwordHash' => $password ?: $password = Yii::$app->security->generatePasswordHash('secret'), 'authKey' => Yii::$app->security->generateRandomString(), 'accessToken' => Yii::$app->security->generateRandomString(64), 'birthday' => $faker->date('Y-m-d', '-15 years'), 'registered' => $faker->dateTimeThisMonth()->format('Y-m-d H:i:s'), ]; }); $factory->state(User::class, 'developer', [ 'status' => 'developer', ]); $factory->state(User::class, 'client', [ 'status' => 'client', ]);
Use Factories
Populate new record without saving
/**@var User $user **/ $user = factory(User::class)->make(); $user = factory(User::class)->states('client')->make(); /**@var User[] $user **/ $users = factory(User::class, 5)->make(); $users = factory(User::class, 5)->states(['client', 'developer'])->make();
Populate and persist records
/**@var User $user * */ $user = factory(User::class)->create(); /**@var User[] $user **/ $users = factory(User::class, 10)->states(['client'])->create(['registered'=>Carbon::now()]);
See more examples in FactoryTest
Use with ActiveFixtures
Create ActiveFixture extended classed in configured directory as usual
class UserFixture extends ActiveFixture { public $modelClass = User::class; protected function getData() { return array_merge( factory(User::class, 1)->states('developer')->raw(), factory(User::class, 10)->states('client')->raw() ); } }
Fixtures with relation dependency
class PostFixture extends ActiveFixture { public $modelClass = Post::class; public $depends = [UserFixture::class]; public function load() { $this->data = []; $users = User::find()->select(['id'])->column(); foreach ($users as $userId) { $posts = factory(Post::class, 5)->create(['createdBy' => $userId]); foreach ($posts as $post) { $this->data[$post->id] = $post->getAttributes(); } } return $this->data; } } class SomeFixture extends ActiveFixture { public $modelClass = Some::class; public $depends = [UserFixture::class]; protected function getData() { $users = User::find()->select(['id'])->where(['status'=>'client'])->column(); $developer = User::find()->where(['status'=>'developer'])->limit(1)->one(); $data = array_merge( factory(Some::class, 5)->raw(['user_id'=>ArrayHelper::random($users)]), factory(Some::class, 20)->states('one')->raw(['user_id'=>function() use(&$users){ return ArrayHelper::random($users);}]), factory(Some::class, 11)->states('two')->raw(['user_id'=>$developer->id]) ); return $data; } }