4
5

More than 3 years have passed since last update.

laravel ファクトリとSedderでデータベースをテスト

Last updated at Posted at 2021-02-19

はじめに

避けては通れないテスト作業。laravelでは簡単にテストができますので備忘録として投稿します。
モデルはModelsというフォルダにて格納しています。
スクショはモデルの設計図になります。
“スクリーンショット” 2021-02-19 23.32.29.jpg

投稿者の環境

MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)
macOS Big Sur バージョン11.0.1
PHP 7.3.23
Laravel Framework 6.20.7

下準備

config\app.phpにある'faker_locale'を下記の様に修正して下さい。ダミーデータが日本語化されます。

app.php
'faker_locale' => 'ja_JP',

ファクトリの生成

ファクトリを作成することによりダミーデータを作成ができます。また、--model=Postオプションにより、ファクトリが生成するモデルの名前を指定できます。このオプションは、生成するファクトリファイルへ指定モデル名を事前に設定します。モデルを作成していたら設定をして下さい。

ターミナル
php artisan make:factory PostFactory --model=Post
Post.php
//階層 Models/Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        // 投稿は複数のコメントを持つ
        return $this->hasMany('App\Models\Comment');
    }

}

フェイカーの作成

マイグレーションファイルと照らし合わせながら作成します。カラムによりプロパティが変わりますのでこちらのチートシートを参考にして下さい。

sample_faker.php
$data[] = [
        'name'     => $faker->name,            // 名前
        'zip'      => $faker->postcode,        // 郵便番号
        'pref'     => $faker->prefecture,      // 都道府県
        'city'     => $faker->city,            // 市
        'address'  => $faker->streetAddress,   // 住所
        'phone'    => $faker->unique()->phoneNumber,     // 電話番号
        'email'    => $faker->unique()->safeEmail,       // メール
        'birthday' => $faker->dateTimeBetween('-80 years', '-20years')
                            ->format('Y-m-d'), // 生年月日 (20〜80年前の日付)
        'score'    => $faker->numberBetween(1, 100), // 1〜100の数字
        'text'     => $faker->realText(20),    // ダミーテキスト 20文字
    ];
PostFactory.php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Models\Post; //Postモデルを参照してテストデータを作成。Modelsというフォルダに格納しているため
use Faker\Generator as Faker;
//  ↓ Post::classのPostはModelsフォルダのPostを参照
$factory->define(Post::class, function (Faker $faker) {
    return [
        'name' => $faker->name,    // 氏名
        'subject' => $faker->realText(16),    // realTextは日本語の投稿場合に必ず使用。
        'message' => $faker->realText(200),    // 200文字のテキスト
        'created_at' => $faker->date('Y-m-d H:i:s', 'now'),
        'updated_at' => $faker->date('Y-m-d H:i:s', 'now'),

    ];
});

create_posts_table.php
//Postsマイグレーションファイル
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
            $table->string('name');
            $table->string('subject');
            $table->text('message');

        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Seederファイルの作成

Seederを作成することによって前述したファクトリのダミーデータを呼び出すことができる様になります。
SeederというのはDBのテスト以外でもく初期値やダミーデータ投入のための仕組みになります。
下記のコマンドを実行するとdatabase/seeds/以下にファイルが生成されます。また、PostsTableSeeder.phpを下記の様に編集して下さい。

ターミナル
php artisan make:seeder PostsTableSeeder
PostsTableSeeder.php
<?php
use Illuminate\Database\Seeder;

class PostsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
public function run()
    {

        factory(App\Models\Post::class, 50) //Postモデルを参照して尚且つ50個のダミーデータを作成
            ->create();
    }
}

外部キーによるファクトリとSeederの設定

CommentにはPost_idという外部キーが割り当てられています。このままテストデータを作成しても

SQLSTATE[HY000]: General error: 1364 Field カラム名 doesn't have a default value

というエラーが発生します。そこで、リレーションを指定することにより外部キーにダミーデータを作成することができます。ファクトリを下記の様に編集します。公式HPリレーションと属性クロージャを参考にしました。

CommentFactory.php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Models\Comment;
use Faker\Generator as Faker;

$factory->define(Comment::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'comment' => $faker->realText(200), 
        'post_id' => factory(App\Models\Post::class),//外部キーを参照
        'created_at' => $faker->date('Y-m-d H:i:s', 'now'),
        'updated_at' => $faker->date('Y-m-d H:i:s', 'now'),
    ];
});
CommentsTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class CommentsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Models\Comment::class, 50)
            ->create();
    }
}

最後に

database/seeds/DatabaseSeeder.phpを開いて、runメソッドに PostsTableSeeder を追加します。

DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // $this->call(UsersTableSeeder::class);
        $this->call(PostsTableSeeder::class);
        $this->call(CommentsTableSeeder::class);
    }
}

ターミナル
$ composer dump-autoload
$ php artisan db:seed

ダミーデータを削除して再度作成したい場合
$ composer dump-autoload
$ php artisan migrate:refresh --seed

成功すると下記のスクショの様になりphpMyAdminにダミーデータが保存されます。
“スクリーンショット” 2021-02-20 0.27.37.jpg
“スクリーンショット” 2021-02-20 0.28.29.jpg

参考URL

データベースのテスト
参考Qiita
参考テスト

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5