[rspec-users] Ability to stub a method differently the second time its called

Tom Stuart tom at therye.org
Wed Jan 26 09:12:41 EST 2011


On 26 Jan 2011, at 13:34, Rob Aldred wrote:

> I'm having a bit of trouble stubbing out a method on a model which has some quite specific behaviour.
> Basically I want to check the method returns something different after ive called update_attributes
> 
> eg.
> 
> @exam.draft?  (returns true)
> @exam.update_attributes(params[:exam])  # sets draft to false
> @exam.draft?  (returns false)
> 
> To give this some context, if the exam is a draft and update_attributes sets draft to false
> then we want to redirect to the show view instead of edit because only exams that are draft can be edited.
> 
> if @exam.draft?
> 	@exam.update_attributes param[:exam]
> end
> 
> if @exam.draft?
> 	redirect_to :action => :edit
> else
> 	redirect_to :action => :show
> end
> 
> I can obviously set consecutive values with and_return(true,false)
> but this feels a bit unreliable? maybe im just confusing myself
> 
> --
> Rob Aldred
> 
> Software Developer
> rob at stardotstar.com
> twitter: stardotstar
> 
> 47 Newton Street, Manchester, M1 1FT
> T: +44 (0) 161 236 9740
> ___________________________________________________
> 
> This email and any files or ideas transmitted within it are sent in 
> confidence and are intended solely for the use of the individual or 
> entity to whom they are addressed. If you have received this email 
> in error please notify the system manager at info at stardotstar.com
> 
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

Hi Rob,

It sounds to me like you're trying to test two different behaviours in one 'it' block, something like:

	it "redirects based on whether the exam is a draft" do
	  @exam.stub!(:draft).and_return(true, false)

	  #make request, assert response redirected to edit
          #make request again, assert reponse redirected to edit   
	end

To describe your behaviour more clearly, you might want to consider splitting this test and using contexts, something along the lines of...

	describe "your action" do
	  context "when exam is a draft" do
	    @exam.stub!(:draft).and_return(true)
	
	      it "redirects to edit" do
	      end 
          end
         
	  context "when exam is final" do
	    @exam.stub!(:draft).and_return(false)

	     it "redirects to "show" do
             end
	  end
	end

Which gives you the benefit of making what you need to stub obvious based on the context.

Hope that helps,

Tom


More information about the rspec-users mailing list