saada/yii2-factory-muffin

为 league/factory-muffin 提供的 Yii2 包装器,带有 Gii 生成器。

2.0.1 2016-12-24 15:16 UTC

This package is not auto-updated.

Last update: 2024-09-22 08:14:17 UTC


README

Version Total Downloads Software License

我发现使用 Yii2 模型维护 fixtures 真的很麻烦。所以我决定编写这个扩展,它基本上包装了 FactoryMuffin,并将工厂定义附加到任何你希望在数据库中播种的模型。我发现这对于动态播种数据库非常有帮助,特别是在编写测试时。如果你之前使用过 FactoryGirl 或 FactoryMuffin,这是为 Yii2 框架量身定制的相同概念。我尽量保持事物尽可能整洁。欢迎贡献!

安装

需要 PHP 5.5+ 和 Composer

在你的 composer.json 中,只需将这些包添加到 "require" 部分

{
    "require": {
        "saada/yii2-factory-muffin": "~2.0",
        "league/factory-muffin-faker": "~2.0"
    }
}

示例用法

<?php
$fm = new saada\FactoryMuffin\FactoryMuffin();
$fm->define('models\Message')->setDefinitions([
    'user_id'      => 'factory|models\User',
    'subject'      => 'sentence',
    'message'      => 'text',
    'phone_number' => 'randomNumber|8',
    'created'      => 'date|Ymd h:s',
    'slug'         => 'call|makeSlug|word',
], function ($object, $saved) {
    // we're taking advantage of the callback functionality here
    $object->message .= '!';
});

$fm->define('models\User')->setDefinitions([
    'username' => 'firstNameMale',
    'email'    => 'email',
    'avatar'   => 'imageUrl|400;600',
    'greeting' => RandomGreeting::get(),
    'four'     => function() {
        return 2 + 2;
    },
]);

所有 FactoryMuffin API 调用都可通过上面的 $fm 实例访问。

替代模型模式(可选)

这种模式是一种便利性,你不必在项目中使用它。但我发现它非常实用,因为我们的许多模型定义(用于测试和假数据)与我们的应用程序模型高度耦合。

首先,我们需要为我们的模型实现 FactoryInterface 接口。

use saada\FactoryMuffin\FactoryInterface;
use League\FactoryMuffin\Faker\Facade as Faker;

class Message extends ActiveRecord implements FactoryInterface
{
    //...
    public function definitions() {
        return [
            [
                'user_id'      => 'factory|'.User::class,
                'subject'      => Faker::sentence(),
                'message'      => Faker::text(),
                'phone_number' => Faker::randomNumber(8),
                'created'      => Faker::date('Ymd h:s'),
                'slug'         => self::class . '::makeSlug',
            ],
            function($object, $saved) {
                // we're taking advantage of the callback functionality here
                $object->message .= '!';
            }
        ];
    }
    //...
}

// and here's my interpretation of what a Yii2 model would look like
class User extends ActiveRecord implements IdentityInterface, FactoryInterface
{
    //...
    public function definitions() {
        $security = Yii::$app->getSecurity();
        return [
            [
                'first_name'           => Faker::firstName(),
                'last_name'            => Faker::lastName(),
                'phone'                => Faker::phoneNumber(),
                'email'                => Faker::email(),
                'auth_key'             => $security->generateRandomString(),
                'password_hash'        => $security->generatePasswordHash('MyFixedTestUserPassword'),
                'password_reset_token' => $security->generateRandomString() . '_' . time(),
            ]
        ];
    }
    //...
}

现在我们有我们的模型,我们可以开始从测试中为我们的数据库播种

use saada\FactoryMuffin\FactoryMuffin;
class MuffinTest extends TestCase {
    //...
    public function testCreateFiveMessages()
    {
        //init factory muffin
        $fm = new FactoryMuffin();
        $fm->loadModelDefinitions([Message::class, User::class]);

        // alternatively you can pass the same array to the constructor
        $fm = new FactoryMuffin([Message::class, User::class]);

        //seed database with 5 messages add set some custom attributes.
        $messages = $fm->seed(5, Message::class, ['created_by' => 1, 'company_id' => 1]);
        Debug::debug($messages);
        $this->assertNotEmpty($messages);

        // confirm that users were created for each message
        foreach ($messages as $message) {
            $this->assertInstanceOf(User::class, $message->user);
        }
    }
}

待办事项

  • 创建围绕 Factory Muffin 3.0 的包装器
  • 创建 Gii 生成器,以自动向模型添加通用的 definitions() 实现