让测试更方便系列:快速创建数据
在写测试的过程中,经常需要创建很多测试数据。根据 Laravel 的文档,我们使用模型工厂方法创建数据。但是默认的模型工厂创建数据的方法只有单条数据,或者相同的多条数据,像这样:
factory(Product::class)->create(['title' => '商品标题']);
而我们的需求经常是创建多条不同的数据,比如这样:
factory(Product::class)->create(['title' => '商品标题1']);
factory(Product::class)->create(['title' => '商品标题2']);
factory(Product::class)->create(['title' => '商品标题3']);
这种情况我们需要写很多条,但是只有一个参数不同,所以我们可以写一个方法来直接创建多条数据:
create(string $model, array $attrs): Collection;
第一个参数是要创建的 Model 类,第二个参数是一个二维数组,可以包含多个模型数据,根据第二个参数的数据条数创建对应数量的模型,然后作为一个集合返回。
当然更进一步,当我们需要像以前那样创建多条一样的数据时,也可以 传入一个数量来告诉方法,我们需要创建多少条数据,所以方法变成了这样:
create(string $model, array $attrs, $amount = null): Collection;
如果有了这个方法,那么上面创建多条数据写法就可以变成:
create(Product::class, [
['title' => '商品标题1'],
['title' => '商品标题2'],
['title' => '商品标题3'],
]);
是不是看上去要简单很多呢。
当然,别忘了我们还有 make
方法,来创建模型,但是不插入数据库,所以要有一个一样签名的 make
方法。
最终我们可以得到这样的实现:
function make($model, $attrs = [], $amount = null)
{
return _makeOrCreate($model, $attrs, $amount, 'make');
}
function create($model, $attrs = [], $amount = null)
{
return _makeOrCreate($model, $attrs, $amount, 'create');
}
function _makeOrCreate($model, $attrs, $amount, $method)
{
if (! isset($attrs[0]) || ! is_array($attrs[0])) {
return factory($model, $amount)->$method($attrs);
}
$lastSubAttrs = [];
$results = collect();
if ($amount === null) {
$amount = count($attrs);
}
for ($i = 0; $i < $amount; $i++) {
if (isset($attrs[$i])) {
$lastSubAttrs = $attrs[$i];
}
$results->push(factory($model)->$method($lastSubAttrs));
}
return $results;
}
可以把这些方法放在一个 tests/helper.php
文件里,然后在 compsoer.json
的 autoload-dev
属性中引用,这样就可以在测试中愉快的使用了。
本作品采用《CC 协议》,转载必须注明作者和本文链接