Laravel/データベースレイヤーとのテスト2

Posted: 2015-05-25 03:03 |  laravel PHP全般 
Laravel/データベースレイヤーとのテスト1 の続きシリーズです
データベースを利用するクラスの疎結合とファンクショナルテスト時のバインディング変更方法を簡単に紹介しました。
ではデータベースを利用したクラスをユニットテストを行いたい場合はどうするのでしょうか!
このクラスでテストしたいものは、データベースに正しく値が書き込まれるかどうかではなく、
意図したSQLが発行されているかどうかなどでしょう。
実際にテストしてみましょう。

実際のデータベースを利用せずにテストするには、sqliteを利用する方法が一般的です。
テスト用にsqliteのファイルを作成しても構いませんが、ここではsqliteのインメモリ機能を利用します。
テストでデータベースの接続先を変更するには.envファイルを用いるのが一番シンプルです。
下記のようにDB_DEFAULTなどを追加して利用します。
この場合はデフォルトにmysqlを利用しますが、テストではsqliteを利用するようにします。

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
DB_DEFAULT=mysql
config/database.phpのdefaultを併せて変更します。
'default' => env('DB_DEFAULT', 'mysql'),

テスト用のsqliteを追加する

インメモリ機能を利用するには次のように記述します。
'testing' => [
    'driver' => 'sqlite',
    'database' => ':memory:',
    'prefix' => '',
    'options' => [
        PDO::ATTR_PERSISTENT => true,
    ]
],
:memory:とすることでインメモリを利用するようになります。
またオプションでPDO::ATTR_PERSISTENTを有効にします。
ここでは接続の度に異なるDBにアクセスすることがないようにこれを指定しています。
(指定の方法はこれ以外にもあります。)

テスト時のドライバを変更する

phpunit.xmlに追記するだけです。
<php>
    <env name="APP_ENV" value="testing"/>
    <env name="DB_DEFAULT" value="testing"/>
    <env name="CACHE_DRIVER" value="array"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="QUEUE_DRIVER" value="sync"/>
</php>
上記のようにテスト時に利用したいenvを指定します。
これでテストに先ほど指定したsqliteのインメモリ機能を利用したドライバが利用されるようになりました。

前回利用したマイグレーションファイルを利用してテストします。
テストでマイグレーションを実行する場合にsetUpメソッドに含めることで実行できますが、
せっかくなのでphpunitのフィクスチャを利用します。
class EntryTest extends TestCase
{
    /** @var  App\Repositories\Eloquent\EntryEntity */
    protected $entry;
    public function setUp()
    {
        parent::setUp();
        $this->entry = new \App\Repositories\Eloquent\EntryEntity();
    }

    /**
     * @before
     */
    public function setUpDatabase()
    {
        $this->artisan('migrate');
    }
}
ビフォーアノテーションを利用してテストを実行前にArtisanコマンドのmigrateが実行します。

SQLをテストする

発行されるSQLをテストする場合はイベントを利用することで簡単にテストすることができます。
allで発行されるSQLをテストする場合は下記のように記述することができます。
    public function testAll()
    {
        \Event::listen('illuminate.query', function($sql) {
            $query = 'select * from "entries"';
            $this->assertEquals($query, $sql);
        });
        $this->entry->all();
    }
illuminate.queryイベントを検知して、発行されたSQLをテストします。
これを利用することでバインドされる値や、
様々な条件で変更されるsql分などを細かくテストすることができるようになります。
EloquentやクエリービルダーはtoSqlメソッドで発行されるSQLを取得できますので、
それらを用いても良いのではないでしょうか?
今回はインメモリ機能とSQLのテストについて簡単に紹介しました!

次回はさらに大きな処理をテストするためのリファクタリングのよていです

about ytake

執筆に参加しています


Laravel お役立ち情報

share



このエントリーをはてなブックマークに追加

Categories

laravel 45

DTM 0

music 0

PHP全般 31

0

JAPAN 1

WORLD 1

javascript 4

RDBMS 1

NoSQL 1

NewSQL 1

Recent Posts

Ad

comments powered by Disqus

GitHub

Social Links

Author


クリエイティブ・コモンズ・ライセンス
Yuuki Takezawa 作『Ytake Blog』はクリエイティブ・コモンズ 表示 - 非営利 4.0 国際 ライセンス で提供されています。

© ytake/comnect All Rights Reserved. 2014