[rspec-users] best practice for model callbacks?

Pat Maddox pat.maddox at gmail.com
Thu Apr 16 14:12:18 EDT 2009


What is the thing that's being done in a callback and also sometimes
called by clients?  Usually the semantics are different and you don't
want to treat them exactly the same...

At any rate, you can be creative with shared example groups to get rid
of the duplication.  Something like

describe "do_something", :shared => true do
  it "should update the posts_count" do
    lambda { do_action }.
      should change(subject, :posts_count).by(1)
  end

  it "should send an email" do
    do_action
    #  however you get emails..I forget
  end
end

describe Foo, "when saved" do
  it_should_behave_like "do_something"

  subject { new_foo }

  def do_action
    subject.save!
  end
end

describe Foo, "when do_something is called" do
  it_should_behave_like "do_something"

  subject { new_foo }

  def do_action
    subject.do_something
  end
end

Does that help?

Pat

On Thu, Apr 16, 2009 at 10:25 AM, Barun Singh <barunio at gmail.com> wrote:
> In many of my models, I have callback methods like this:
>
> class MyModel < ActiveRecord::Base
>
>   before_save   :do_something
>
>   def do_something
>     some code here...
>   end
>
> end
>
> The do_something method is a public method that is sometimes called on its
> own, and also called whenever the model is saved.  Let's say there are six
> specs that are required to fully test the do_something method.  What is
> considered best practice for how the before_save filter should be tested?
> If I say that I'm only ever going to test the behavior, it means that I need
> to basically rewrite those six specs to make sure they hold whenever the
> model is saved, as well as when the do_something method is called
> explicitly.  I don't like having to repeat myself this way, particularly
> considering that a model may have multiple callbacks like this so I end up
> having to repeat myself a lot.  The alternative is to just do something
> like:
>
> x = MyModel.new
> x.should_receive(:do_something)
> x.save
>
> But of course this tests implementation rather than behavior which is
> usually not desirable.  But in this situation I'm tending to prefer it over
> having to do a ton of rewriting of specs.  What are others' thoughts on
> this?
>
> Thanks..
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list