Edited at
CakePHPDay 11

CakePHP&PHPUnitのsetUp・tearDownの挙動の細かい話

More than 1 year has passed since last update.


はじめに

これはCakePHP Advent Calendar 2017の11日目の記事です。

おはようございます、@Khigashiguchiです。

普段の業務でCakePHPを書いています。

業務中でちょっと詰まったときに調べたテストのこと、特にsetUp・tearDownの挙動を書き残してみようと思います。


目次


  • 環境情報

  • 背景

  • CakePHPの中身

  • 調査結果

  • 最後に


環境情報


  • PHP 5.3

  • CakePHP 2.3

  • PHPUnit 3.7


背景

Controllerのテストを書いていた時、ふと以下のようなことをしたいと思いました。

「テスト実行前に、Configureの中身を一部書き換えておきたい。」

pubic class HogehogeControllerTestCase extends ControllerTestCase

{
public function setUp()
{
parent::setUp();
// Configureの中身を書き換えたい
if (Configure::check('Debug.host')) {
$this->origin_host = Configure::read('Debug.host');
}
Configure::write('Debug.host', 'localhost');
}

public function tearDown()
{
parent::tearDown();
// HERE: 書き換えたConfigureを元の状態に戻す

}

このときにtearDown()で明示的にConfigureの中身を戻すような処理は書いた方がいいんだろうか。

どうすべきか迷ったので、CakePHPの中身を見てみました。


CakePHPの中身

CakePHPがoverrideしているsetUp()・tearDown()メソッドは、lib/Cake/TestSuite/CakeTestCase.php内にあります。


setUp()

/**

* Setup the test case, backup the static object values so they can be restored.
* Specifically backs up the contents of Configure and paths in App if they have
* not already been backed up.
*
* @return void
*/

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

if (empty($this->_configure)) {
$this->_configure = Configure::read();
}
if (empty($this->_pathRestore)) {
$this->_pathRestore = App::paths();
}
if (class_exists('Router', false)) {
Router::reload();
}
}

PHPUnitのsetUp()を呼び出してから、実行前の状態をインスタンス変数に格納しています。

テスト実行前のConfigureを Configure::read() でインスタンス変数に格納しています。


tearDown()

/**

* teardown any static object changes and restore them.
*
* @return void
*/

public function tearDown() {
parent::tearDown();
App::build($this->_pathRestore, App::RESET);
if (class_exists('ClassRegistry', false)) {
ClassRegistry::flush();
}
if (!empty($this->_configure)) {
Configure::clear();
Configure::write($this->_configure);
}
if (isset($_GET['debug']) && $_GET['debug']) {
ob_flush();
}
}

setUpと同じく、PHPUnitのtearDown()を呼び出してから、以下の後片付けをしてくれてます。


  • ClassRegistryの片付け

    ClassRegistry::initでModelを読んだ場合は、この処理で後片付けしてくれそうです。


  • Configureを実行前の状態に戻す

    setUp()で取っておいた$this->_configureを使って実行前の状態に戻しています。


  • bufferをFlush



調査結果

ConfigureはCakePHPの機構の中でConfigureを元どおりに戻してくれそうなので冒頭のコードでは、tearDownで何もしなくても大丈夫そうです。


最後に

悩んだときはコードを読むのが一番早いですね。

来年も、バージョンはしっかり上げつつCakePHPer頑張ります!

以上