Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can RSpec stubbed method return different values in sequence?

I have a model Family with a method location which merges the location outputs of other objects, Members. (Members are associated with families, but that's not important here.)

For example, given

  • member_1 has location == 'San Diego (traveling, returns 15 May)'
  • member_2 has location == 'San Diego'

Family.location might return 'San Diego (member_1 traveling, returns 15 May)' The specifics are unimportant.

To simplify the testing of Family.location, I want to stub Member.location. However, I need it to return two different (specified) values as in the example above. Ideally, these would be based on an attribute of member, but simply returning different values in a sequence would be OK. Is there a way to do this in RSpec?

It's possible to override the Member.location method within each test example, such as

it "when residence is the same" do    class Member     def location       return {:residence=>'Home', :work=>'his_work'} if self.male?       return {:residence=>'Home', :work=>'her_work'}     end   end   @family.location[:residence].should == 'Home' end 

but I doubt this is good practice. In any case, when RSpec is running a series of examples it doesn't restore the original class, so this kind of override "poisons" subsequent examples.

So, is there a way to have a stubbed method return different, specified values on each call?

like image 403
Mike Blyth Avatar asked May 10 '11 09:05

Mike Blyth


2 Answers

You can stub a method to return different values each time it's called;

allow(@family).to receive(:location).and_return('first', 'second', 'other') 

So the first time you call @family.location it will return 'first', the second time it will return 'second', and all subsequent times you call it, it will return 'other'.

like image 176
idlefingers Avatar answered Oct 15 '22 07:10

idlefingers


RSpec 3 syntax:

allow(@family).to receive(:location).and_return("abcdefg", "bcdefgh") 
like image 41
nothing-special-here Avatar answered Oct 15 '22 05:10

nothing-special-here