让测试更方便系列:快速创建数据

在写测试的过程中,经常需要创建很多测试数据。根据 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.jsonautoload-dev 属性中引用,这样就可以在测试中愉快的使用了。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Laravel YES !
wkan
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!