😗
factoryのstatesを利用して分かりやすくテストデータを用意する(Laravel)
Laravelのfactoryはテストデータを生成する際にかなり便利です。
ユニットテストや結合テストのコードを書く際は僕も結構factoryにはお世話になっていますが、 実はfactoryの1つの機能である「states」を使用するともっと分かりやすくテストデータを用意できます。
※factoryの書き方はLaravel8でちょっと変わりましたが、今回のサンプルコードはLaravel8系の書き方です。
factoryファイル内部にstatesを記述する
usersテーブルを想定します。
usersテーブルには、メール認証をしたかどうかを意味する email_verified_at
カラムと利用規約に同意したかどうかを意味する agreed_at
というカラムがあります。
statesを使用することで、「メール認証をしたユーザー」、「メール認証をしたけど利用規約にまだ同意していないユーザー」 などに名前をつけることができます。
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* メール認証済み&利用規約に同意しているユーザー
*
* @return array
*/
public function definition()
{
return [
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'agreed_at' => now(),
];
}
/**
* メール認証をしていない
*/
public function emailNotVerified()
{
return $this->state(fn () => [
'email_verified_at' => null,
'agreement_date' => null,
]);
}
/**
* メール認証をしていて、利用規約に同意していない
*/
public function notAgreed()
{
return $this->state(fn () => [
'email_verified_at' => now(),
'agreement_date' => null,
]);
}
}
上記のfactoryであれば、テストデータはこのように呼び出すことができます
// メール認証をしていないユーザーを作成する
$user = User::factory()->emailNotVerified()->create();
// 利用規約に同意していないユーザーを作成する
$user = User::factory()->notAgreement()->create();
デメリットはコード補完ができないことなので、どんなstatesを定義したっけな?って思ったらわざわざfactoryのファイル内を見に行く必要があります。
しかしこのように名前をつけておくとコードを見る人にとってはすごく見やすいですよね。
コードは書くよりも読まれる方が何百倍と多いということを聞いたので、このように読みやすさを重視していくのはとてもいいことだと思います。
Discussion