2012-10-24 9 views
6

Angenommen, ich habe die folgende Active Klasse:Gibt es eine saubere Möglichkeit, ActiveRecord-Callbacks in Rspec zu testen?

class ToastMitten < ActiveRecord::Base 
    before_save :brush_off_crumbs 
end 

Gibt es eine saubere Art und Weise zu testen, dass :brush_off_crumbs hat als before_save Rückruf eingestellt?

Mit „reinigen“ Ich meine:

  1. „Ohne tatsächlich zu speichern“, weil
    • Es ist langsam
    • Ich brauche nicht zu testen, dass Active richtig eine before_save Richtlinie behandelt; Ich muss testen, dass ich richtig sagte es was zu tun, bevor es spart.
  2. "Ohne Hacking durch undokumentierten Methoden"

fand ich eine Art und Weise, die Kriterien # 1, aber nicht # 2 erfüllt:

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 

Antwort

9

Verwenden run_callbacks

Dies ist weniger hacky aber nicht perfekt:

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 

Die Verwendung dieser Technik für einen after_save Test wäre peinlicher.

+0

das ist die eleganteste Art, die ich gesehen habe! Danke vielmals! – rickypai

+0

Gibt es etwas wie 'run_callbacks' für Controller-Callbacks? – Dennis

+2

Für ein 'after_save' könnten Sie wahrscheinlich' 'soll_receive' 'in den Block setzen und' true 'zurückgeben, d. H .: ' revenue_object.run_callbacks (: save) do; revenue_object.should_receive (: record_financial_changes); wahr; Ende –

Verwandte Themen