クマのブログ

つまづいたところ、学びを書いていきます

【Laravel8】Factory(Faker)の書き方が前バージョンと違う

前提

Windows 10

・Laravel 8.0

背景

Laravel実践開発を進めていく中で参考書通り進めたがつまづく。 模索した結果、解決したのでメモ

事象

P284「ユニットテスト」をファクトリ使って実施する際、Factoryの定義が8.0になってから変わった。

詳細

書籍はLaravel5.8を前提にしているので、バージョン違いによる記法の違いが生じた。

具体的にはファクトリ―ファイル内でfakerを作る際の記述が異なっていた

↓書籍(5.8)

<?php
use App\Person;
use Faker\Generator as Faker;
​
$factory->define(Person::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'mail' => $faker->email,
        'age' => $faker->numberBetween(1,100),
    ];
});

試したこと

公式のサイトで記法を確認

「こういう基本的な情報は1次情報が一番!」

ということで、日本語版公式サイトを参考に以下の通り記述。

↓自分の環境(8.0)

<?php
​
namespace Database\Factories;
​
use App\Person;
use Illuminate\Database\Eloquent\Factories\Factory;
​
class PersonFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Person::class;
​
    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'mail' => $this->faker->safeEmail,
            'age'  => $this->faker->numberBetween(1,100),
        ];
    }
}

結果:正常に動いた!

主な違い

5.8では

  • Factoryクラスからdefineメソッドを使っている

  • defineメソッド内のクロージャでFakerクラスのインスタンスが引数として使われ、Faker生成は

'name' => $faker->name,
'mail' => $faker->email,
'age' => $faker->numberBetween(1,100),

このように書いている。

一方、8.0はFactoryクラスを継承したうえで、definitioinメソッドを利用し、以下のように記述

'name' => $this->faker->name,
'mail' => $this->faker->safeEmail,
'age'  => $this->faker->numberBetween(1,100),

自分のインスタンス($this)からfakerプロパティを経由して生成するfakerへアクセスする必要があるのは手間だが

defineメソッドとdefinitionメソッドではクロージャ関数を使う必要や$Fakerインスタンスを引数にとる必要がなくなった。

所感

・内容自体はすぐ解決した。

・「なぜこの書き方に変わったか?」については上述の

自分のインスタンス($this)からfakerプロパティを経由して生成するfakerへアクセスする必要があるのは手間だが

defineメソッドとdefinitionメソッドではクロージャ関数を使う必要や$Fakerインスタンスを引数にとる必要がなくなった。

より、可読性を意識したことによるものかと推測。

まだ、理解がふわっとしているので、まだまだたくさんLaravelに触れること必要がありそうだ。

参考

Laravel実践開発