ああ、今更Cake2の書くのはちょっと・・・と思わないでもないのですが、Kobitoの肥やしにしておくだけっていうのも悲しみがあるので下書き放出ポスト。
掲題のとおりです。
「モデルは難儀すること無くモック化できた、しかしビヘイビアはどうするのじゃ〜」と少し考えさせられた機会があったので。試し見てたらできた、というメモ。
Behaviorがどう読み込まれるか
ClassRegistry::getObject($class);
みたいな処理をしていますね。
ここの返り値を制御できれば勝てそう
ClassRegistryは、どうやってクラスを出し入れしているの?
- そのキーに対応するオブジェクトが登録されていれば、それを返す
- 二重読み込みとかをいい感じに避けるアレ
- 未ロードだったら、対応するクラスを探してきて返す
つまり「予めモックを登録」しておけば良い・・?
ClassRegistry::addObject()の存在
「キーに対応するオブジェクト」とさらっと書きましたが、実際に「登録」を行っているメソッドがこちらです。
hiromi2424さんの記事
実例で言えば、フレームワーク中のコードModelにおいて、「自身(=モデルクラス)自身のコンストラクタ内で、自身を登録する」という処理が行われています。
ClassRegistry::addObject($this->alias, $this);
# http://api.cakephp.org/2.6/source-class-Model.html#727
これによって、「Userモデルがインスタンス化された時に、key:Userに対して$Userを紐付ける」が実現するわけですね。
ビヘイビアについても同様なので、つまり「HogeBehevior
が読み込まれようとした時に、何を返すか」はアプリケーション側から制御可能というわけです。
実際にビヘイビアをモック化してみる
モデルの単体テストにおいて、HogeBehavior
はテストスコープ外なんだぜ・・・!という時。
testのSetUp()中でやってみる例。
public function setUp() {
parent::setUp();
// 最初に「実際のクラスを扱えるように登録」して、
App::import('Model/Behavior', 'HogeBehavior');
// 読み込めるようになったクラスからモックを作成し
$HogeBehavior = $this->getMock('HogeBehavior', ['someMethod']);
// `HogeBehavior`として、実際のビヘイビアではなくモックを登録する
ClassRegistry::addObject('HogeBehavior', $HogeBehavior);
}
これで行けるようになります。