はじめに
こんばんは。
夜中子供が寝ているときに粛々と仕事と勉強をしております。
表題通りlaravel8でテストデータを作ったのですが、昔やってたlaravelのバージョンとは作り方違ってたので、備忘録として残しておきます。
本番
1. コンフィグの修正
config/app.php
を修正して fakerで日本語を使用できるようにします。
'faker_locale' => 'ja_JP',
1. Factory作成
makeコマンド実行
$ php artisan make:factory UserProfileFactory Factory created successfully.
できたFactoryクラスを以下みたいに修正
<?php namespace Database\Factories; use App\Model\UserProfile; use Illuminate\Database\Eloquent\Factories\Factory; class UserProfileFactory extends Factory { protected $model = UserProfile::class; // 対象となるModelクラスを指定 public function definition() { // return値の値を作成(fakerを使ってダミーデータを作成) return [ 'name' => $this->faker->name, 'postal_code' => $this->faker->postcode(), 'prefecture' => $this->faker->prefecture(), 'address' => $this->faker->city() . $this->faker->streetName() . $this->faker-> streetAddress() ]; } }
2. Modelに必要なtraitをuseする
makeコマンド実行
php artisan make:model UserProfile Model created successfully.
作成されたmodelには HasFactory
traitがuseされていると思いますが、makeコマンド介さずにmodelクラスを作った場合は以下のように HasFactory
traitをuseします。
<?php namespace App\Model; use Database\Factories\UserProfileFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; class UserProfile extends Model { use HasFactory; // ← 対象のtrait protected static function newFactory() { return UserProfileFactory::new(); // ← 対象のFactoryを指定する } }
3. SeederでFactoryを指定してテストデータを作成する
makeコマンド実行
$ php artisan make:seeder UserProfileSeeder Seeder created successfully.
できたSeederファイルでFactoryを使用してデータを作成
<?php namespace Database\Seeders; use App\Model\UserProfile; use Illuminate\Database\Seeder; class UserProfileSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { UserProfile::factory(100)->create(); // これで100件のテストデータが作成できる // テストデータの一部 or 全てを上書きしたい場合 UserProfile::factory()->create([ 'name' => 'あいうえお' // nameだけテストデータではなく 「あいうえお」 にする ]); } }
番外編 factoryで使用するfakerに新たなメソッドを生やす
作成したfactoryクラスの親クラスである Illuminate\Database\Eloquent\Factories\Factory
に存在している withFaker()
をオーバライドして以下のように新たにproviderを作ります。
protected function withFaker() { $faker = parent::withFaker(); $faker->addProvider(new class($faker) extends \Faker\Provider\Base { public function ngWord(): string { return $this->generator->randomElement([ 'バカ', 'アホ', 'マヌケ' ]); } }); return $faker; }
これで $this->faker->ngWord()
が使えるようになります。
baseクラスを新たに作って生やしてもいいし、 HasFactory
trait側のメソッドをオーバライドして対応とか、色々やり方はありそうです。
終わりに
久々にlaravel使っているんですが、テストデータとか作りやすいですね。
現場からは以上です。