プログラミング 美徳の不幸

Ruby, Rails, JavaScriptなどのプログラミングまとめ、解説、備忘録。

サンドイッチメソッドの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