テスト用のダミーデータを作成する際、factoryをよく使います。factoryを使ったダミーデータの作成方法は色々ありますが、今回は単一Modelのデータ作成でよく使う記述をご紹介します。

factoryの定義

factoryを使用するには、事前にfactoryにモデルの属性値を定義する必要があります。
まず、Userモデルに対してのfactoryの定義です。

class UserFactory extends Factory
{
    public function definition()
    {
        return [
            'name'        => $this->faker->name(),
            'email'       => $this->faker->unique()->safeEmail(),
            'active_flag' => 'Y',
        ];
    }
}

作成したfactoryを対象のUserモデルへHasFactoryのトレイトで紐付すると、

use Illuminate\Database\Eloquent\Factories\HasFactory;

class User extends Model
{
    use HasFactory; //★
    ....
}

事前準備は完了です。次にテストデータを作成してみます。

テストデータの作成とDB保存

makeメソッドを使うと、インスタンスの作成のみでDBへは保存されません。

$user = User::factory()->make();

上記をtinkerで実行してみると、以下のようなインスタンスが作成されました。factoryで定義したname・email・active_flagのプロパティは、ちゃんとダミーデータになっていますね。

= App\Models\User {#29806
    name: "木村 直子",
    email: "jun.yoshida@example.com",
    active_flag: "Y",
  }

次は、インスタンスを作成しDBにも保存する場合です。createメソッドを使用します。

User::factory()->create();

tinkerでの実行結果は、以下となります。DBに保存されているので、生成されたデータにはcreated_atやupdated_atも割り当てられています。

= App\Models\User {#29843
    name: "工藤 里佳",
    email: "watanabe.rika@example.net",
    active_flag: "Y",
    updated_at: "2023-05-21 16:41:50",
    created_at: "2023-05-21 16:41:50",
    id: 21,
  }

factoryで定義していないidが割り振られているのは、Userテーブルにidカラムが主キーとして設定されているためです。

では次は、複数のデータを作成してみましょう。以下のようにfactoryに生成したい数を指定します。今回は10としました。

$users = User::factory(10)->create();

tinkerで実行した結果がこちらになります。先ほどまでと違い、返り値はCollectionとなっていますね。

= Illuminate\Database\Eloquent\Collection {#29785
    all: [
      App\Models\User {#29795
        name: "喜嶋 治",
        email: "miki66@example.org",
        active_flag: "Y",
        updated_at: "2023-05-21 17:12:34",
        created_at: "2023-05-21 17:12:34",
        id: 101,
      },
      App\Models\User {#29799
        name: "江古田 陽子",
        email: "jtsuda@example.org",
        active_flag: "Y",
        updated_at: "2023-05-21 17:12:34",
        created_at: "2023-05-21 17:12:34",
        id: 102,
      },
... 以下省略

2つ目以降の実行結果は省略しましたが、Collectionの中にUserモデルインスタンスが10生成されています。tinkerでカウントしてみると、以下のように10あるのが分かります。

> $users->count();
= 10

また、テストではプロパティを任意の値に指定したい場合が多いと思います。以下のようにcreateメソッドに配列を指定すると指定したプロパティのオーバーライドができます。

        User::factory()->create([
            'name'        => 'テストユーザー',
            'active_flag' =>  'N',
        ]);

nameとactive_flagの値を指定しました。tinkerの実行結果を見ると、ちゃんと指定した値で生成されているのがわかります。

= App\Models\User {#29789
    name: "テストユーザー",
    email: "gyamaguchi@example.net",
    active_flag: "N",
    updated_at: "2023-05-21 17:24:30",
    created_at: "2023-05-21 17:24:30",
    id: 112,
  }

いずれも最後にcreateメソッドを付けないと、データはDBに保存されないのでご注意ください。

By hmatsu