LumenプロジェクトでDBを使用した部分のテストをする(Sqlite in-memory)


[Lumen](https://lumen.laravel.com/)フレームワークを使用したプロジェクトのテストを書く．

通常実行時とテスト実行時で使用するDBを分けるのがミソ

同じDBを使う設定にしているとCI/CDツールを用いたテストにこける時が多々ある．

## 環境

|項目|バージョン|
|:---:|:---:|
|OS|macOS Sierra ver.10.12.5|
|php|5.6|
|Lumen|5.2.9|

## サンプルプロジェクト
すでにテストなしの実装が完了している小さなapiです．
[ダウンロード](https://github.com/shu920921/lumen_news_api/archive/without_test.zip)

振る舞いは[LumenでDBと連携した簡単なapiを作ってみる](http://qiita.com/shu920921/items/f20ccccea6881991dbcb#%E5%AE%9F%E8%A3%85)に書いてあります．

手元で動かしたいって方は使用してください．
`.env`ファイルがないので`.env.sample`をコピーして適宜変更してくださいね．
`composer install`も忘れずに

## 実装
### テスト時の設定
`phpunit`を用いてテストをする．
`phpunit.xml`を編集

```xml:phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="bootstrap/app.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false">
    <testsuites>
        <testsuite name="Application Test Suite">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist>
            <directory suffix=".php">app/</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <!--以下を追加-->
        <env name="DB_CONNECTION" value="testing"/>
    </php>
</phpunit>
```

このファイルでテスト時の設定をいろいろいじることができます(できるらしい)が今回は1番シンプルな方法でいきます．


この`<php>`タグ内の記述はアプリケーションの環境変数を設定していますね．通常実行時はアプリケーションルート配下の`.env`を参照しますが，テスト時はここを参照するようです．

そして`DB_CONNECTION`に`testing`を設定したのですが，これは`vendor/laravel/lumen-framework/config/database.php`の

```php:database.php

・・・
	
'testing' => [
            'driver' => 'sqlite',
            'database' => ':memory:',
        ],
        
        ・・・
```

の部分を参照しています．このファイルにmysqlやsqlite使用の設定も書いてあります．

Laravelでは`config`ディレクトリがアプリケーションルート下に置かれてるのにLumenにはないので一応記述しておきました．

### Migration & Seeding
`database/migrations`，`database/seeds`以下にそれぞれ記述していく．

インメモリDBを使用するため，テストの都度MigrationとSeedingをしていく必要がある．

Migration，Seedingの記述をしても，それだけだと正常にテストされません．
テスト実行時にMigrationとSeedingが実行される設定が記述されていないからです．

その設定は`RoutingTest`が継承している`TestCase`クラスに記述します．

```tests/TestCase.php
<?php
use \Illuminate\Support\Facades\Artisan;
class TestCase extends Laravel\Lumen\Testing\TestCase
{
    /**
     * Creates the application.
     *
     * @return \Laravel\Lumen\Application
     */
    public function createApplication()
    {
        return require __DIR__.'/../bootstrap/app.php';
    }
    /**
     * Create the TestDatabase
     */
    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
        Artisan::call('db:seed');
    }
}
```

`setUp`メソッドを追加しました．
このメソッドはテストが実行される前に実行されます．

*このTestCaseクラスでは`Facade`を利用しているため，`bootstrap/app.php`の`$app->withFacades();`をコメントインしといてくださいね．

### テスト

`./vendor/bin/phpunit`で実行できます．

```
$ ./vendor/bin/phpunit
PHPUnit 4.8.35 by Sebastian Bergmann and contributors.

..

Time: 614 ms, Memory: 14.25MB

OK (2 tests, 4 assertions)
```

長くなってしまいましたが，問題なくテストが通りましたね．

## サンプル
今回，Migration,Seedingのところは割愛したので気になる方は，[Migration](https://github.com/shu920921/lumen_news_api/tree/master/database/migrations)，[Seeding](https://github.com/shu920921/lumen_news_api/tree/master/database/seeds)を参考にしてみてください