[rspec-users] Shared Helpers

Pat Maddox mailinglists at patmaddox.com
Tue Feb 23 13:34:35 EST 2010


I just use a factory method.

describe 'Authorize.net CIM gateway', :shared => true do
  describe 'saving a card' do
    describe 'preconditions' do
      it "should raise an error if the card is not saved" do
        lambda {
          gateway.save_credit_card(Factory.build(:credit_card, :user => Factory(:user)))
        }.should raise_error(ArgumentError, /unsaved record/)
      end
    end

    describe 'first card saved on an account' do
      it "should set the authorize_id on the credit card" do
        credit_card = Factory :credit_card, :user => Factory(:user)
        gateway.save_credit_card credit_card
        credit_card.authorize_id.should be_present
      end

      it "should return true for a successful response" do
        credit_card = Factory :credit_card, :user => Factory(:user)
        gateway.save_credit_card(credit_card).should be_true
      end

      it "should mark the card as having a validated card code" do
        card = Factory :credit_card, :card_code_validated => false
        gateway.save_credit_card card
        card.should be_card_code_validated
      end
    end

  # etc etc etc etc
  end
end


describe Payment::AuthorizeNetCim::FakeGateway do
  def gateway
    @gateway ||= Payment::AuthorizeNetCim::FakeGateway.new
  end

  it_should_behave_like 'Authorize.net CIM gateway'
  
  # some extra custom examples
end

I prefer this to requiring an instance variable, because you get built in error-handling for free.  If you don't implement the factory method, you get "undefined method: gateway" rather than the less obvious undefined method on NilClass error.

Also, your :locals => { :entry => Entry.new } syntax is going to be no good because you'll only have one instance of Entry that gets reused across examples.  No bueno.  You'd have to do
:locals => lambda { { :entry => Entry.new } }
and now it's just getting ugly.

If you think defining methods is too heavy (which I wouldn't agree with, but okay) then maybe use the let method?

describe Entry do
  before do
    let(:entry) { Entry.new )
  end

  it_should_behave_like "an_entry"
end

How's that look?

Pat



On Feb 23, 2010, at 9:30 AM, Scott Taylor wrote:

> 
> Has there been any development on shared helpers / it_should_behave_like feature in rspec?
> 
> I forget the reasons, but I remember a patch for something like this was rejected:
> 
>    it_should_behave_like "an_entry", :locals => { :entry => Entry.new }
> 
> OR:
> 
>    before do
>      @entry = Entry.new
>    end
> 
>    it_should_behave_like "an_entry", :locals => lambda {
>      { 
>        :entry => @entry
>      }
>    }
> 
> Is there any code which now deals with the variable passing issue in rspec?
> 
> Best,
> 
> Scott
> 
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list