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

Rob Aldred Rob.aldred at stardotstar.com
Mon Jan 31 07:39:58 EST 2011


On 26 Jan 2011, at 15:29, David Chelimsky wrote:

> On Jan 26, 2011, at 7:34 AM, 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)
> 
> You're testing the framework here. Why?
> 
>> 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
> 
> My first question is why the update_attributes needs to be conditional? Couldn't you just do:
> 
> @exam.update_attributes param[:exam]
> 
> if @exam.draft?
> 	redirect_to :action => :edit
> else
> 	redirect_to :action => :show
> end

Published (not draft) exams are not allowed to be edited

We are using couchDB the couchrest_model gem does not implement ActiveModel::Dirty
so there is no way to check for changing values eg...   draft_was or draft_changed? so implementing a validator in the model is a pain without making another call to the db to check the current draft status before_save

The reason for the double conditional because if the user passes the draft param set to false (To make the exam published) we need to allow them to save the instance.

We then use the 2nd conditional to decide where to send them based on the final state of the exam instance
whether draft was changed or not.

> 
> If it must be the way you have it, I wouldn't do this with stubs on the @exam itself. I'd do what you need to do to set the exam in a draft state (Factory(:exam, :draft => true)???), and then invoke the controller action with :draft => true in one example, and :draft => false in the other.
> 
> That make sense?
> 
> 

Yes, this would work and your right I guess I was testing the framework.
This seems like a workable solution.

Thanks for your time.
Rob





More information about the rspec-users mailing list