silvertipsoftware/factorygirl

Laravel4/Eloquent的FactoryGirl端口

v0.2.1 2014-03-28 06:37 UTC

This package is auto-updated.

Last update: 2024-09-16 06:44:58 UTC


README

FactoryGirl是(或希望是)一个相对忠实的thoughtbot/factory_girl端口,这是一个用于测试的Ruby领域对象工厂库。

安装

Composer

silvertipsoftware/factorygirl添加到你的composer.json文件中的require-dev部分

"require-dev": {
    "silvertipsoftware/factorygirl": "dev-master"
}

你可以显然选择任何可用的版本。运行composer update来获取它。

Laravel

将FactoryGirl ServiceProvider添加到你的Laravel应用中

'providers' => array(
    ...
    'SilvertipSoftware\FactoryGirl\FactoryGirlServiceProvider',
    ...
),

(可选) 将以下代码片段添加到你的app/config/app.php文件中

'aliases' => array(
    ...
    'Factory' => 'SilvertipSoftware\FactoryGirl\Facades\FactoryGirl',
    ...
),

支持的PHP版本

目前支持PHP 5.3+。PHP 5.4可能会让一些事情变得更好,所以未来版本可能会有所改变。

文档

查看FactoryGirl文档,了解其功能和用途。语法是希望直接转换为PHP。

工厂定义

使用app/tests/factories.php文件来存储工厂定义,它将在第一次构建/创建对象时自动加载。

基本工厂

Factory::define('room', function($f) {
    return array(
        'name' => 'Meeting Room',
        'capacity' => 5,
        'notes' => 'Great views'
    });
});

定义了一个Room Eloquent模型的工厂,并设置了namecapacitynotes属性。模型类名是从工厂名称推断出来的。如果不想这样,也可以指定模型类名。

Factory::define('large_room', function($f) {
   return array(
      'name' => 'Banquet Hall',
      'capacity' => 200
   ); 
}, array(
    'class' => 'Room'
));

构建/创建对象

使用上面定义的工厂,你的测试代码可以这样做

$room = Factory::build('room');
$another = Factory::build('large_room');

来获取新的房间实例,这些实例不会保存到数据库中。如果你想持久化它们,请使用create

$room = Factory::create('room');

在任一情况下,都可以通过传递一个数组作为第二个参数来覆盖属性

$extra_large_room = Factory::create('large_room', array(
    'capacity' => 1000
));

序列

序列基于传递给闭包的递增索引返回一个值。这对于以标准方式创建唯一属性非常有用。

Factory::sequence('email', function($n) {
    return 'noreply'.$n'.@somedomain.com';
});

然后,在工厂中,你可以通过以下方式使用序列

Factory::define('user', function($f) {
    'username' => 'Joe Public',
    'email' => $f->next('email'),
    'status' => 'active'
});

关联

给定一个account模型的工厂,你可以使用以下方式将其与user模型关联起来

Factory::define('user', function($f) {
    return array(
        'username' => 'Joe Public',
        'email' => $f->next('email'),
        'account' => $f->associate()
    );
});

当构建user时,将创建一个account实例,并将useraccount_id设置为引用新的account。目前,仅支持belongsTo关系,并且唯一的“构建策略”是将关联的对象保存到数据库中。

可以通过传递一个数组来覆盖关联对象中的属性值

        ...
        'account' => $f->associate( array(
            'plan' => 'platinum'
        )) 
        ...

要使用的工厂是从属性名称推断出来的。如果希望使用不同的工厂,请将其传递给associate调用

Factory::define('user', function($f) {
   return array(
      'username' => 'Richie Rich',
      'email' => $f->next('email'),
      'account' => $f->associate('paid_account')
   ); 
});

或者,指定工厂和覆盖项

Factory::define('user', function($f) {
   return array(
      'username' => 'Richie Rich',
      'email' => $f->next('email'),
      'account' => $f->associate('paid_account', array(
         'plan' => 'platinum'
      ))
   ); 
});

闭包作为属性

闭包也可以作为属性值传递,它在模型构建时会被评估。这允许你在构建时执行更复杂的逻辑。这对于3个对象的关联特别有用。例如

Factory::define('room', function($f) {
    return array(
        'name' => 'Meeting Room',
        'account' => $f->associate(),
        'location' => function($room,$f) {
            return $f->associate( array(
                'account' => $room['account']
            );
        }
    );
});

属性值按照在工厂定义中给出的顺序进行评估,所以上面将accountlocation交换将不会起作用。

继承

可以将工厂链式调用以重用常见的属性定义,如下所示

Factory::define('room', function($f) {
    return array(
        'name' => 'Room 100',
        'capacity' => 5
    );
});

Factory::define('room_with_notes', function($f) {
    return array(
        'notes' => 'This is a nice room.'
    );
}, array(
    'parent' => 'room'
));

$room = Factory::build('room_with_notes');
echo $room->name; // Room 100
echo $room->notes; // This is a nice room.