テスト用のダミーデータを作成する際、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に保存されないのでご注意ください。