ModelFactoryを利用したインスタンスの生成

今回のお題

今回のお題は「ModelFactoryを用いたテスト用のインスタンスの生成」です。

以前にテストコードについては一度取り上げました。

あの時にテストしたのは、テーブルにレコードが保存されていなくても行える部分のみでした。

なので今回は、一歩進めて、テスト用のインスタンスを保存するための仕組みについてまとめていきます。

目次

  • ModelFactoryとは
  • ModelFactoryファイルの作成方法
  • 作成されたModelFactoryファイルの中身
  • ModelFactoryの編集方法
  • ModelFactoryを用いて実際にインスタンスを生成するには

ModelFactoryとは

ModelFactoryとは、テストコード内で利用するインスタンスを作成するためのLaravelの仕組みです。

具体的にいうと、database/factoriesディレクトリに各モデルに対応したModelFactoryファイルを作成し、その中にインスタンスを作成するルールを記述することで、テストの際にそれに沿ってインスタンスを作成することができるようになります。

ModelFactoryファイルの作成

それでは、ModelFactoryファイルを作っていきます。

例えばBookモデルに対応するFactoryを用意するのであれば、以下のコマンドをターミナルで実行することになります。

php artisan make:factory BookFactory --model=Book

make:factoryの後にファイル名を、--model=の後に対応するモデル名を指定してください。

これで、BookFactory.phpが作成されます。

作成されたModelFactoryファイルの中身

作成されたModelFactory中身は以下のようになっています。

ちなみに、UserLicenseというのが今回Factoryを作成したモデル名です。

<?php

namespace Database\Factories;

use App\Models\UserLicense;
use Illuminate\Database\Eloquent\Factories\Factory;

class UserLicenseFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = UserLicense::class;// 対応するモデル名を明記

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()// ここに、インスタンスの生成について記述する
    {
        return [
            //
        ];
    }
}

 

基本的には赤字部分のpublic function definition(){return;};のreturnの内部が、インスタンスの生成に関するルールを記述する箇所になります。

具体的な記述方法は、事項で説明していきます。

ModelFactoryファイルの編集方法

ModelFactoryファイルのreturn[]の中を編集することで、生成するインスタンスのプロパティの値を決めることができます。

記述例としては以下のようになります。

return [

    "name" => $this->faker->name,

    "age" => $this->faker->numberBetween(0, 100),

    "comment" => $this->faker->paragraph

];

基本的には、"カラム名" => $faker->項目名という形式ですね。

$fakerに関する書き方についてはGitHubのFakerの項目に詳しく書いてあるので、一旦は省略します。

ModelFactoryを用いたインスタンスの生成

では、実際にModelFactoryを用いてインスタンスを生成してみましょう。

この場合には、以下のように記述します。

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

(XxxにはModelFactoryの対象にしたモデル名が入る。)

 

ちなみに、LaravelのテストにはsetUpメソッドと呼ばれるメソッドがあります。

これは、テスト実行時に最初に必ず実行されるもので、この中でFactoryを用いてインスタンスを生成しておくのが一般的です。

以下、setUpを用いた書き方の例です。

protected function setUp():void// ①

{

    parent::setUp();// ②

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

}

 

念のため、上記で下線をつけた部分について解説しておきます。

①:voidについて

これは、テストコードの中で定義しているsetUpメソッドの戻り値の型を定義するために使用します。

voidとは戻り値がない、という意味です。

echoで文字列を出力するだけの場合やインスタンスをテーブルに保存する場合は戻り値がないのでvoidになります。

逆に、returnで何かしらの値を返す場合は、string, integer, booleanなど何かしらの型が戻り値に設定されることになります。

 

では、なぜ戻り値の型を明示する必要があるのかという話をします。

全てのテストコードはTestCaseクラスを継承して作られているのですが、setUpメソッドは元々TestCaseクラスに定義されているメソッドになります。

つまり、今行っているのはメソッドのオーバーライドになるわけですね。

その場合には、上書き後も戻り値の型が変わっていないことを示さないとエラーになるので、このように型を明示しています。

 

②parent::setUp();について

これは、TestCaseクラスで定義されているsetUpメソッドの呼び出しを行なっています。

TestCaseクラスのsetUpメソッドは全てのテストの事前処理として必須の処理を定義しているので、上書き後もそれらの処理が実行されるようにしているのですね。

 

ちなみに、テストコード内でfakerを用いてインスタンスを作成する場合には、テストコードファイルの

use PHPUnit/Framework/Testcase;

use Tests/TestCase;

に書き換える必要があります。

ご注意を。

終わりに

以上が、ModelFactoryを用いたインスタンスの生成方法になります。

もちろん外部キーを絡めるなどのより高度な方法もまだまだあるのですが、そちらについては機会があれば取り上げていきます。