2
2

More than 3 years have passed since last update.

LaravelでRedisのテストにFaker(Factory)を使う

Last updated at Posted at 2020-06-21

先生はfですか?zですか?

ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪


------------------- ↓ 余談はここから ↓-------------------

Laravelを使っていて、
CSVファイルをデータベースに登録する際、
一時的に利用するデータをテーブル創って入れていたのだが、
Redisでよくね?
と思い立ってしまった。

で、データベースのテストにはFactoryやSeedを使ってるわけだけど、
Redisでも使えるようにならんかなぁ :thinking:
となったのでちょっとやってみた。

また、訳わからんこと。。。 :upside_down:

とりあえず動くレベルで、
形にはなったのでここに残しておこう。

Laravelのバージョンはこちら

$ php artisan --version
Laravel Framework 5.7.28

テーブル構造はこんな感じ

item_name item_num item_price
$faker->name $fake->randomDigit $fake->randomDigit

ファイル構成はこんな感じ
全部ジェネレーターで作るので、
あらかじめ作っておく必要はない。

app/FakeModel.php
database/factories/FakeModelFactory.php
tests/Unit/FakeModelTest.php

fakerfa●ker と打ち間違える日々


------------------- ↓ 本題はここから ↓-------------------

Factoryの生成

兎にも角にもFactoryを創る。
Factory名はFakeModelFactory。
モデルのクラス名をFakeModelとする。

$ php artisan make:model -f FakeModel         # モデルとfactory同時生成の場合
$ php artisan make:factory -m FakeModel FakeModelFactory # factory単独の場合

factoryデータの調整

database/factories配下に指定したファイル名のfactoryが生成される。
これを実際の利用データの形に書き換えておく。

database/factories/FakeFactory.php
$factory->define(App\FakeModel::class, function (Faker $faker) {
    return [
        "item_name" => $faker->name,
        "item_num" => $faker->randomDigit,
        "item_price" => $faker->randomDigit,
    ];
});

テストの生成

実行するテストを用意

$ php artisan make:test Units/FakeModelTest
tests/Unit/FakeModelTest.php
use Illuminate\Support\Facades\Redis;
use Symfony\Component\VarDumper\VarDumper;
use Faker\Factory as FakerFactory;  // ←↓名前かぶるのでalias
use Illuminate\Database\Eloquent\Factory as EloquentFactory;

class FakeModelTest extends TestCase
{
    public function FakeGenerator() {
        $class = FakeModel::class; // ←ここは自由なモデルに変更できる
        $attributes = [];          // ←factory()->createの引数
        $faker = FakerFactory::create();
        $factory = EloquentFactory::construct($faker)->load(database_path('factories'));
        $model = $factory->make($class, $attributes); // ←フェイクデータ入りモデル生成
        return $model->toArray();
    }

    public function testFake() {
        VarDumper::dump($this->FakeGenerator());
    }
}

これでテストランナーを走らせると、
適当データが出力されているはず。

$ ./vendor/bin/phpunit tests/Unit/FakeModelTest 
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.
^ array:3 [
  "item_name" => "Lilla Howell"
  "item_num" => 3
  "item_price" => 8
]

:triumph:

テストランナーを叩く度に違うデータになる。
便利だな :no_mouth:


------------------- ↓ 後書はここから ↓-------------------

意外と簡単? :thinking:
内部を解析してコンパクトにまとめるのに丸一日かかったですよ。 :disappointed_relieved:

作ってみてわかったが。
フェイクデータ入りモデルが生成されるので、
苦労してモックを作らなくてもいいってことかな。
応用範囲は広そうだ。
ただ、当たり前だけどクエリビルダーとかは使えません。

タイトルのRedisが一個も出てこないじゃんと思われたかもだが、
ちゃんとテストをしている。

tests/Unit/FakeModelTest.php
//上記に追記
    public function testRedis(){
        $items = $this->FakeGenerator();

        $key = 'fake:item';
        Redis::hmset($key, array_values($items));
        var_dump(Redis::hgetall($key));
        Redis::del($key);
    }

Redisがdocker上にあるのでdocker経由でテストランナーを実行

$ docker-compose exec php-fpm vendor/bin/phpunit tests/Unit/FakeModelTest
R^ array:3 [
  0 => "Mr. Trent Kerluke"
  1 => "8"
  2 => "7"
]
2
2
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
2
2