makeabledk / laravel-factory-enhanced
Requires
- php: ^8.1
- illuminate/database: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- fakerphp/faker: ^1.21
- laravel/laravel: ^10.0|^11.0
- mockery/mockery: ^1.5
- phpunit/phpunit: ^10.5
This package is auto-updated.
Last update: 2024-09-27 14:21:55 UTC
README
Laravel Factory Enhanced 🔥
将eloquent关系的魔力带入Laravel Factory。
传统上,如果你想创建一个团队并添加一些用户,你需要手动创建团队和用户,然后再次将它们关联起来。这很容易导致非常冗长的测试。
Laravel 7.x及更早版本
$team = factory(Team::class)->create(); $users = factory(User::class)->times(2)->create(); foreach ($users as $user) { factory(TeamMember::class)->create([ 'team_id' => $team, 'user_id' => $user, 'role' => 'admin' ]); }
Laravel 8.0及以后版本
$team = Team::factory() ->hasAttached( User::factory()->count(2), ['active' => true] ) ->create();
Laravel Factory Enhanced
$team = Team::factory() ->with(2, 'users', ['pivot.role' => 'admin']) ->create();
安装
您可以通过composer安装此包
composer require makeabledk/laravel-factory-enhanced
版本
Laravel 8+ 类式工厂
本包的版本4及以后与Laravel 8引入的新类式语法兼容。
Laravel 7之前的工厂
本包的版本3及更早与传统的$factory->define()
语法兼容。请在此处查看文档 v3文档
升级到v4的指南
升级到本包的v4版本所需的大部分重构工作在于重写工厂以与Laravel类式工厂兼容。
如果您在升级到Laravel 8时使用Laravel Shift,许多这项工作将自动完成,您将很快走上正轨。
重写为类式工厂
请使用Laravel Shift升级Laravel版本,或参考官方文档了解如何使用类式方法编写工厂。
应用状态
在您的测试套件中将所有->state('some-state')
的出现替换为->someState()
。
预设
本包引入的预设概念现在可以简单地重写为状态。
因此,在您的测试套件中将所有->preset('some-preset')
的出现替换为->somePreset()
。
Times方法
在您的测试套件中将所有->times(x)
的出现替换为->count(x)
。
工厂辅助语法
此更改完全可选。如果您愿意,可以将您的测试套件中所有出现factory(SomeModel::class)
的地方更改为SomeModel::factory()
。
如果您选择这样做,请记住在所有模型中添加use \Makeable\LaravelFactory\Factory;
。
其他重大变更
已从Factory实例中删除了odds()
方法。
使用方法
安装包后,您的工厂应扩展Makeable\LaravelFactory\Factory
,而不是原生的Laravel Factory
类。
此外,请确保在您的模型上使用相应的Makeable\LaravelFactory\HasFactory
特质。
例如
app/Models/User.php
<?php namespace App\Models; use Makeable\LaravelFactory\HasFactory; class User { use HasFactory; // ... }
database/factories/UserFactory.php
<?php namespace Database\Factories; use Makeable\LaravelFactory\Factory; class UserFactory extends Factory { public function definition() { return [ // ... ]; } }
现在您可以使用您熟悉的Laravel所有原生功能,以及本包提供的附加功能。
如果您不熟悉Laravel工厂,请参阅官方文档:https://laravel.net.cn/docs/master/database-testing
简单关系
您可以使用增强的工厂创建模型上定义的任何其他关系。
示例:一个具有sites()
关系(多对多)的Server
模型
Server::factory()->with(3, 'sites')->create();
请注意,您仍然可以使用您熟悉的任何本地功能,例如状态和属性
Server::factory()->online()->with(3, 'sites')->create([ 'name' => 'production-1' ]);
多重关系
您可以在同一工厂上指定多个关系。
鉴于我们之前的 Server
模型还有一个名为 team
的关系(属于),您可以这样做
Server::factory() ->with('team') ->with(3, 'sites') ->create();
现在您将有一个 1 team
,它拥有 1 server
,该 server
又有 3 sites
。
嵌套关系
接下来是更高级的使用场景,您还可以进行嵌套关系。
例如,我们可以使用嵌套重写之前的示例
Team::factory() ->with(3, 'servers.sites') ->create();
请注意,计数 '3' 适用于 最终关系,在这种情况下 sites
。
如果您想要 2 个服务器,每个服务器都有 3 个站点,您可以写成以下格式
Team::factory() ->with(2, 'servers') ->with(3, 'servers.sites') ->create();
关系中的状态
就像您可以在因子模型上指定预定义的状态(见官方文档)一样,您也可以将完全相同的状态应用于关系。
Team::factory() ->with(2, 'online', 'servers') ->create();
您可能会发现自己想要一个处于多个状态的关系。在这种情况下,您可以使用 andWith
方法。
Team::factory() ->with(2, 'online', 'servers') ->andWith(1, 'offline', 'servers') ->create();
通过使用 andWith
,我们将创建一个 '清晰的分割点',这样任何对 with
的后续调用都不会干扰 andWith
之前指定的关系。
在上面的示例中,任何进一步的关系嵌套都将应用于 '离线' 服务器。
Team::factory() ->with(2, 'online', 'servers') ->andWith(1, 'offline', 'servers') ->with(3, 'servers.sites') ->create();
上面的示例将创建 1 个团队,该团队拥有
- 2 个在线服务器
- 1 个离线服务器,有 3 个站点
在关系中填充属性
您可以通过将它们作为参数传递给 with
方法来在关系上填充属性。
factory(Team::class) ->with(2, 'servers', ['name' => 'laravel.com']) ->create();
如果关系是 belongs-to-many 关系,您还可以通过在属性名称前加上 pivot.
来填充关联模型上的属性。
Team::factory() ->with(2, 'users', ['pivot.role' => 'admin']) ->create();
使用 apply()
所有上述使用 with
方法配置关系的示例也可以应用于基本模型,使用 apply
方法。
例如
Server::factory() ->apply(2, 'online', ['name' => 'laravel.com']) ->with(3, 'mysql', 'databases') ->create();
这将创建 2 个在线服务器,每个服务器都有 3 个 mysql 数据库。
事实上,通过使用本包的 HasFactory
特性,您甚至可以将这些参数传递给 ::factory()
方法本身
Server::factory(2, 'online', ['name' => 'laravel.com']) ->with(3, 'mysql', 'databases') ->create();
使用闭包进行自定义
除了直接将 count 和 state 传递给 with
函数外,您还可以传递一个闭包,该闭包将直接接收 FactoryBuilder
实例。
在闭包中,您可以执行在 FactoryBuilder
上所做的所有操作,包括如果您愿意,还可以进一步嵌套关系。
Team::factory() ->with('servers', fn (ServerFactory $servers) => $servers ->count(2) ->active() ->with(3, 'sites') ) ->create();
没有定义工厂的因子模型
传统上,在没有任何定义的工厂的模型上尝试使用 Model::factory()
会抛出异常。不再是这样了!
安装此包后,您完全可以使用静态的 Model::factory()
方法在任意使用 Makeable\LaravelFactory\HasFactory
特性的 Eloquent 模型上。
此外,此包还恢复了古老的 factory(Model::class)
辅助函数,您可以在任何模型上使用它,无论该模型是否有定义的工厂或使用 HasFactory
特性。
示例
factory(2, Server::class)->with(1, 'sites')->create();
可用方法
这些是在 Factory
实例上提供的额外方法,除了核心方法。
- apply
- fill
- fillPivot(仅适用于 BelongsToMany
- pipe
- tap
- with
- andWith
测试
您可以使用以下命令运行测试
composer test
贡献
我们很高兴接受额外的功能拉取请求。请参阅CONTRIBUTING 以获取详细信息。
致谢
许可证
署名-相同方式共享 4.0 国际。有关更多信息,请参阅许可证文件。