以前のエントリで「CakePHPでModelのテストが失敗する時の対応」というのを書いたが、 ついにスッキリと解決することが出来た!
原因
結局のところ、原因はクラスのオートローダーにあった。 CakePHPの仕組みでは、クラスのオートローダーとして App::load()関数が使われている。
ところが・・・ Composer経由でinstallしたPHPUnitを利用してテストを行う場合、PHPUnit自体の読み込みとしてComposerのautoloaderを利用するので、 phpunitのtest実行時は、オートローダーが2種類存在することになる。
1つ目 => Composerのオートローダー ※test実行の為、PHPUnitが先に読み込まれている必要がある。
2つ目 => CakePHPのオートローダー
そして、Composer側のオートローダーには、なんとbakeしたModel名のロード設定が書かれている、こんな感じに!
1 | 'MyUser' => $vendorDir . '/pear-pear.cakephp.org/CakePHP/Cake/Test/Case/Model/models.php' |
上の例でいくと、MyUserというmodelのテストを実行すると、クラスのオートローダーが実際にテストしたいmodelを読み込む前に CakePHPのcore側のディレクトリにあるテスト用のMockモデルを読みにいってしまう。
こうなるとお手上げで、自分の作ったModelは絶対に読み込まれないので、前エントリでやったようにオートローダーが動くより前に 絶対パスでincludeするしか、手がなくなってしまう。
※ちなみにオートローダーの使用する関数をチェックするには、spl_autoload_functions関数を使えば一発。これトテモトテモ大事。
解決法
core側のディレクトリにあるモックモデルの定義ファイルから、テストしたいModel名のモッククラス定義を削除します。
1 | $ vi Vendor/pear-pear.cakephp.org/CakePHP/Cake/Test/Case/Model/models.php' |
こんな記述があるから、マルっと削除 bake時に同時にtestも作るとここに追加される模様。
1 | /** |
そんでもって、composerのautoloaderを、以下のコマンドで再作成します。
1 | php composer.phar dump-autoload |
これにて、App::usesの記述だけで、自分の作成したModelが読み込めるようになりました。 ( ´ー`)フゥー...大分手間取ってしまった。
教訓
(1)クラスが読み込まれない場合は、オートローダーでの読み込みがうまくいってないという勘が働くようにすること!
(2)オートローダーで使われる関数は、spl_autoload_functions()関数で確認できる。ワスレナイこと。( ゚д゚ )クワッ!!