在寫測試的過程中,經常需要建立很多測試資料。根據 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 協議》,轉載必須註明作者和本文連結