Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You are on the right track, but I have run into a number of frustrating unexpected message errors when using rSpec, observers, and mock objects. When I am spec testing my model, I don't want to have to handle observer behavior in my message expectations. </p> <p>In your example, there isn't a really good way to spec "set_status" on the model without knowledge of what the observer is going to do to it. </p> <p>Therefore, I like to use the <a href="http://patmaddox.com/2007/11/23/better-rails-testing-decoupling-observers/" rel="noreferrer">"No Peeping Toms" plugin.</a> Given your code above and using the No Peeping Toms plugin, I would spec the model like this: </p> <pre><code>describe Person do it "should set status correctly" do @p = Person.new(:status =&gt; "foo") @p.set_status("bar") @p.save @p.status.should eql("bar") end end </code></pre> <p>You can spec your model code without having to worry that there is an observer out there that is going to come in and clobber your value. You'd spec that separately in the person_observer_spec like this: </p> <pre><code>describe PersonObserver do it "should clobber the status field" do @p = mock_model(Person, :status =&gt; "foo") @obs = PersonObserver.instance @p.should_receive(:set_status).with("aha!") @obs.after_save end end </code></pre> <p>If you REALLY REALLY want to test the coupled Model and Observer class, you can do it like this:</p> <pre><code>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 </code></pre> <p>99% of the time, I'd rather spec test with the observers turned off. It's just easier that way. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload