CakePHP2系でComponentの単体テストを行って躓いた話
概要
CakePHP2系のアプリケーションに、新規でComponentを作成した。 そのComponentに対して、単体テストを行うとしたところ躓いたので残しておく。
内容
Componentに対して単体テストを作成し、公式ドキュメントを参考にsetUpに下記を記述。
public function setUp() { parent::setUp(); $CakeRequest = new CakeRequest(); $CakeResponse = new CakeResponse(); $this->Controller = new テスト用Controller($CakeRequest, $CakeResponse); $Collection = new ComponentCollection(); $this->Component = new テスト対象のComponent($Collection); $this->Component->startup($this->Controller); }
これでテストケースを書いて実行したところ、テストケースが正常に走らなかった。 エラーログを確認したところ、下記が出力されている。
Error: Fatal Error (1): Call to a member function メソッド名() on a non-object
この出力されたメソッドはテスト用Controllerの親クラス(AppController)に定義されており、Webページとしてアクセスする分には問題なく利用できている。
何が原因なんだ…。
解決
テストケースのsetUp内に $Collection->setController($this->Controller);
を追加することで解決した。
エラーログを見ると、メソッドがないと怒られているので テスト対象のComponent
内でControllerから受け取った値を見てみた(下記コードのgetController結果)。
すると、値がnullとなっており、Controllerがセットされていないことがわかった。
public function __construct(ComponentCollection $collection, $settings = array()) { $this->Controller = $collection->getController(); parent::__construct($collection, $settings); }
getがあるなら、setがあるだろうとCakePHPのコードを確認したところ、setControllerがあったのでビンゴ。 setControllerを呼び出すことで解決した。
public function setUp() { parent::setUp(); $CakeRequest = new CakeRequest(); $CakeResponse = new CakeResponse(); $this->Controller = new テスト用Controller($CakeRequest, $CakeResponse); $Collection = new ComponentCollection(); $Collection->setController($this->Controller); $this->Component = new テスト対象のComponent($Collection); $this->Component->startup($this->Controller); }
以上、誰かのためになったら良いなと思い残しておきます。 最後まで読んで頂きありがとうございました。
参考
https://book.cakephp.org/2.0/ja/development/testing.html#id27