サンドイッチメソッドのstub化
現在作っているGithub風のアプリケーションでは、Controllerが実在するファイルシステムのブランチを切り替えることがある。
Controllerでブランチの操作を意識し、モデル側ではブランチを気にしないで済むという構成。
当初はControllerにrender, DB操作, flashというようなよくある操作以外のものが混入するのが気持ち悪かったものの、今ではむしろそれをモデル側に仕事させるほうが気持ち悪くて、Controllerから仕事させるのは正しいと思っている。
で、問題はだいたい以下のようなコードになるわけだけど、
def create @branch.checkout do #=>Branch#checkoutがブランチを切り替える @branch.build_kommit(params[:kommit]) ..... end end
もしテストで@branchがモックオブジェクトだったりすると当然実体のブランチ切り替えをしてもらうと困るのだから、checkoutは黙っていてほしい。
どうするか?
◯ひとまず思いついた解決策
@branch.instance_eval do def checkout(&block) block.call end end
実際のBranch#checkoutの実装を削ったものをテスト実行中のみ動的にオーバーライドする。
◯RSpecを調べて見つけた方法
@branch.stub(:checkout).and_yield
下のほうが簡単。ただ、引数がうんたらかんたらとか言い出すと混乱しそう。
上と下は自分のテストの動作では同じような挙動だったけど、本当にそうなのかよくわからないから違うという人がいたら教えて下さいm(__)m