2012-10-24 8 views
6

は、私は次のActiveRecordクラスがあるとします。RspecでActiveRecordコールバックをテストするきれいな方法はありますか?

class ToastMitten < ActiveRecord::Base 
    before_save :brush_off_crumbs 
end 

:brush_off_crumbsbefore_saveコールバックとして設定されていることをテストするためのクリーンな方法はありますか?私が意味する「クリーン」と

    • それは
    • 私はActiveRecordのが正しくbefore_saveディレクティブを扱うことをテストする必要はありませんが遅いですので、「実際には保存しません」。私は正確にそれをテストする必要がありますそれは保存する前にそれを言った。
    • "文書化されていない方法でハッキングなし"

私は条件#1を満たす方法を見つけなく#2:

it "should call have brush_off_crumbs as a before_save callback" do 
    # undocumented voodoo 
    before_save_callbacks = ToastMitten._save_callbacks.select do |callback| 
    callback.kind.eql?(:before) 
    end 

    # vile incantations 
    before_save_callbacks.map(&:raw_filter).should include(:brush_off_crumbs) 
end 

答えて

9

使用run_callbacks

これはあまりハックです完全ではありません。

it "is called as a before_save callback" do 
    revenue_object.should_receive(:record_financial_changes) 
    revenue_object.run_callbacks(:save) do 
    # Bail from the saving process, so we'll know that if the method was 
    # called, it was done before saving 
    false 
    end 
end 

after_saveをテストするためにこの手法を使用すると、より扱いにくいでしょう。

+0

これは私が見た最もエレガントな方法です!どうもありがとう! – rickypai

+0

コントローラコールバックのための 'run_callbacks'のようなものはありますか? – Dennis

+2

'after_save'の場合、ブロック内に' should_receive'を入れてtrueを返します。すなわち、 'revenue_object.run_callbacks(:save)do; revenue_object.should_receive(:record_financial_changes);真; end' –

関連する問題