Frage

Angenommen, Sie haben ein ActiveRecord::Observer in einem Ihrer Ruby on Rails-Anwendungen - wie tun Sie test dieses Beobachters mit rSpec?

War es hilfreich?

Lösung

Sie sind auf der richtigen Spur, aber ich habe laufen in eine Reihe von frustrierenden unerwartete Nachricht Fehler bei der Verwendung von rSpec, Beobachter und mock-Objekte.Wenn ich die spec Tests mein Modell, ich nicht wollen, zu behandeln Beobachter Verhalten in meiner Nachricht Erwartungen.

In Ihrem Beispiel gibt es keinen wirklich guten Weg spec "set_status" auf das Modell ohne zu wissen, was die Beobachter tun, um es.

Daher benutze ich gerne das "Nein Peeping Toms" - plugin. Ihr code oben und mit der "Nein" Peeping Toms plugin, ich würde spec-Modell wie dieses:

describe Person do 
  it "should set status correctly" do 
    @p = Person.new(:status => "foo")
    @p.set_status("bar")
    @p.save
    @p.status.should eql("bar")
  end
end

Sie können spec Ihre Modell-code, ohne befürchten zu müssen, dass es Beobachter gibt, die gehen, um in und verpasste Ihr Wert.Sie würden spec, die separat in der person_observer_spec wie diese:

describe PersonObserver do
  it "should clobber the status field" do 
    @p = mock_model(Person, :status => "foo")
    @obs = PersonObserver.instance
    @p.should_receive(:set_status).with("aha!")
    @obs.after_save
  end
end 

Wenn Sie wirklich, WIRKLICH wollen, um zu testen, das gekoppelte Modell und Beobachter-Klasse, Sie können tun wie diese:

describe Person do 
  it "should register a status change with the person observer turned on" do
    Person.with_observers(:person_observer) do
      lambda { @p = Person.new; @p.save }.should change(@p, :status).to("aha!)
    end
  end
end

99% der Zeit, die ich lieber Skillung-test-mit dem Beobachter ausgeschaltet.Es ist nur einfacher so.

Andere Tipps

Haftungsausschluss:Ich habe eigentlich nie getan, das auf eine Produktionsstätte, aber es sieht aus wie ein sinnvoller Weg wäre die Verwendung von mock-Objekten should_receive und Freunde, und das aufrufen von Methoden für die Beobachter direkt

Gegeben das folgende Modell und Beobachter:

class Person < ActiveRecord::Base
  def set_status( new_status )
    # do whatever
  end
end

class PersonObserver < ActiveRecord::Observer
  def after_save(person)
    person.set_status("aha!")
  end
end

Ich würde schreiben mit der Spezifikation wie folgt aus (ich habe es, und es geht)

describe PersonObserver do
  before :each do
    @person = stub_model(Person)
    @observer = PersonObserver.instance
  end

  it "should invoke after_save on the observed object" do
    @person.should_receive(:set_status).with("aha!")
    @observer.after_save(@person)
  end
end

no_peeping_toms ist jetzt ein Juwel und kann hier gefunden werden: https://github.com/patmaddox/no-peeping-toms

Wenn Sie möchten, um zu testen, ob der Beobachter beobachtet das richtige Modell und erhält die Meldung, wie erwartet, hier ein Beispiel mit RR.

your_model.rb:

class YourModel < ActiveRecord::Base
    ...
end

your_model_observer.rb:

class YourModelObserver < ActiveRecord::Observer
    def after_create
        ...
    end

    def custom_notification
        ...
    end
end

your_model_observer_spec.rb:

before do
    @observer = YourModelObserver.instance
    @model = YourModel.new
end

it "acts on the after_create notification"
    mock(@observer).after_create(@model)
    @model.save!
end

it "acts on the custom notification"
    mock(@observer).custom_notification(@model)
    @model.send(:notify, :custom_notification)
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top