2012-10-24 34 views
6

假設我有以下的ActiveRecord類:是否有一種乾淨的方式來測試Rspec中的ActiveRecord回調?

class ToastMitten < ActiveRecord::Base 
    before_save :brush_off_crumbs 
end 

有沒有乾淨的方式來測試:brush_off_crumbs已被設置爲before_save回調?

通過 「乾淨」 我的意思是:

  1. 「沒有實際保存」,因爲
    • 它很慢
    • 我並不需要測試ActiveRecord的正確處理一個before_save指令;我需要測試我是否正確告訴它保存之前要做什麼。
  2. 「沒有通過無證方法黑客」

我發現滿足條件#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' –

相關問題