Phalconを使用したUnitTest環境の整備（for Mac）

# Phalconを使用したUnitTest環境の整備（for Mac）

Phalconに依存したUnitTestを書く場合に、phalcon.soのExtensionが必要となる

## Phalcon Extensionのインストール

開発環境にphalcon.soが必要なため事前にインストールを行う

### Mac（El Capitan）

* **phpenv** で該当のPHPをインストールする
	* see http://qiita.com/omega999/items/c5b1c177331f8d342efd
* **brew** でphalcon extensionをインストールする

```shell-session
    brew tap homebrew/dupes
    brew tap homebrew/versions
    brew tap homebrew/php
    brew install php56-phalcon
```
* `brew info php56-phalcon` で `phalcon.so` をさがす
	* 例） /usr/local/Cellar/php56-phalcon/2.0.13
* `php.ini` に `phalcon.so`のExctensionを足す

```
	extension=/usr/local/Cellar/php56-phalcon/2.0.13/phalcon.so
```
* 確認

```shell-session
	# php -i | grep "phalcon => enabled"
	phalcon => enabled
```

* **composer install --dev** を実行してテスト環境用のモジュールをインストールする。phpunitを実行するためにrequire-devのモジュールが必要となる。
 
```json:composer.json
    "require-dev": {
        "mockery/mockery": "0.9.4",
        "phpunit/phpunit": "4.7.6",
        "phalcon/incubator": "^2.0"
    }
```
* phpunit実行時に読み込まれるbootstrap.phpの作成
	* see https://docs.phalconphp.com/ja/latest/reference/unit-testing.html

```
require_once APP_PATH . '/vendor/autoload.php';
...その他、PhalconのDIコンテナ作成など記述
```

* `phpunit.xml`の作成

```xml:phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
        bootstrap="bootstrap.php"
        colors="true"
        convertErrorsToExceptions="true"
        convertNoticesToExceptions="true"
        convertWarningsToExceptions="true"
        verbose="true"
        stopOnFailure="true"
        processIsolation="false"
        backupGlobals="false"
        syntaxCheck="true"
        >
    <testsuite name="sample tests">
        <directory>./tests</directory>
    </testsuite>
</phpunit>
```

* テストコード作成

```php:UnitTestCase.php
<?php

use Phalcon\Di;
use Phalcon\Test\UnitTestCase as PhalconTestCase;

class UnitTestCase extends PhalconTestCase
{
    /**
     * @var \Voice\Cache
     */
    protected $_cache;

    /**
     * @var \Phalcon\Config
     */
    protected $_config;

    /**
     * @var bool
     */
    private $_loaded = false;

    public function setUp()
    {
        parent::setUp();

        // テスト中に必要になる追加のサービスを読み込み
        $di = Di::getDefault();

        // ここで必要なDIコンポーネントを取得する。config があるなら、それを parent に渡すことを忘れずに

        $this->setDi($di);

        $this->_loaded = true;
    }

    public function testSimpleSample()
    {
        $this->assertEquals('works',
            'works',
            'This is OK'
        );
    }


    /**
     * Check if the test case is setup properly
     *
     * @throws \PHPUnit_Framework_IncompleteTestError;
     */
    public function __destruct()
    {
        if (!$this->_loaded) {
            throw new \PHPUnit_Framework_IncompleteTestError('Please run parent::setUp().');
        }
    }
}
```

* 実行
	* **phpunit.xml**がある場所で
	* `vendor/phpunit/phpunit/phpunit tests/Test.php`
	* 自分のローカルにインストールした（パスが通っている）phpunitとcomporserで指定したphpunitとのバージョンの違いに注意すること


# PHPUnit用テストの書き方の基本

1. **Class** という名前のクラスのテストは、**ClassTest** という名前のクラスに記述
2. テスト用のメソッドには、**test*** という名前で始まるパブリックメソッドにする
3. テストメソッドの中で **assertEquals()** のようなアサーションメソッドを使用して、期待される値と実際の値が等しいことを確かめる

see https://phpunit.de/manual/current/ja/writing-tests-for-phpunit.html