LoginSignup
8
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-12-10

はじめに

これは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頑張ります!

以上

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4