user icon

Laravelのテスト用便利トレイトの動作を変えてみる

Laravel 5.5 です。

Laravelにはunit test等の際にuseするとよろしくやってくれるトレイトがあります。
昨日の記事に出てきたRefreshDatabaseやDatabaseMigrations、他にはDatabaseTransactions、WithoutMiddleware、WithoutEventsがあります。

本当に便利なのですが、すこし動作を調整したいこともあります。

例えばDatabaseMigrationsでマスターの流し込みまでやりたいとか。

フレームワーク内を調べるとsetUpTraits()でトレイトがuseされたかを判定し、特定のメソッドを呼ぶようになっていることがわかります。

    protected function setUpTraits()
    {
        $uses = array_flip(class_uses_recursive(static::class));

        if (isset($uses[RefreshDatabase::class])) {
            $this->refreshDatabase();
        }

        if (isset($uses[DatabaseMigrations::class])) {
            $this->runDatabaseMigrations();
        }

        if (isset($uses[DatabaseTransactions::class])) {
            $this->beginDatabaseTransaction();
        }

        if (isset($uses[WithoutMiddleware::class])) {
            $this->disableMiddlewareForAllTests();
        }

        if (isset($uses[WithoutEvents::class])) {
            $this->disableEventsForAllTests();
        }

        return $uses;
    }

このメソッドをapp/tests/TestCase.phpやDuskTestCase.phpでオーバーライドして自分が作ったトレイトを実行するようにもできます。

例えば私の場合、データベースダンプをリストアするSnapshotLoadというトレイトを作成して追加しています。

    protected function setUpTraits()
    {
        $uses = array_flip(class_uses_recursive(static::class));
        if (isset($uses[SnapshotLoad::class])) {
            // DatabaseTransactionsの前に実行する必要がある。
            $this->runSnapshotLoad();
        }
        return parent::setUpTraits();
    }

閑話休題、前回記事の最後のテストサンプルでのDatabaseMigrationsの動作を変更してみましょう。呼び出されるrunDatabaseMigrationsメソッドを別名に変更し、新たに定義します。

<?php
namespace Tests\Browser;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use App\User;

class LoginTest extends DuskTestCase
{
    use DatabaseMigrations 
    {
        runDatabaseMigrations as runDatabaseMigrationsOrg; //名前変える
    }
    //DatabaseMigrationsの動作カスタマイズ
    public function runDatabaseMigrations()
    {
        $this->runDatabaseMigrationsOrg();  //元々の処理を実行
        \Artisan::call('db:seed', ['--class' => 'MasterSeeder']);
    }

    public function testLogin()
    {
        $user = factory(User::class)->create();

        $this->browse(function (Browser $browser) use ($user) {
            $browser->visit('/login')
                    ->type('email', $user->email)
                    ->type('password', 'secret')
                    ->press('ログイン')
                    ->assertPathIs('/home');
        });
    }
}

元々のDatabaseMigrationsの処理後にマスター設定用のMasterSeederが実行されます。

Facebooktwitterlinkedintumblrmail

Tags:

Comments are closed.