Ashley Moran
2006-Dec-18 12:04 UTC
[rspec-users] should_receive and multiple return values
Hi I just got bit by a misunderstanding about and_return. I''ve got this controller method parse_parameters that loops over query string parameters and parses out vehicle registration dates. We have to turn these into one of three bands (Jan-Feb, Mar-Aug, Sep- Dec) so I wrote a method (registration_date_to_band_year_and_month) takes a date and returns two return values, the year and month of the band. I thought this would work: specify "should turn the provided registration date into a CAP band" do CapFutureResidual.should_receive (:registration_date_to_band_year_and_month).with(Date.new(2003, 9, 30)).and_return(2003, 9) CapFutureResidual.should_receive (:registration_date_to_band_year_and_month).with(Date.new(2005, 3, 1)).and_return(2005, 3) controller.parse_parameters( { :capid26149 => "rd2003-09-30,mi40000,ft15", :capid30125 => "rd2005-03-01,mi73825,ft42" } ) end But it doesn''t because and_return is setting up multiple method calls, not multiple return values. I don''t imagine multiple return values are used that often, but they can be handy. Would there be any use in another method, maybe and_return_values or something to allow you to specify them? Since they are possible in Ruby, it makes sense that you should be able to specify them in RSpec. I got around it, of course, using an array return and the * expand operator, but I avoid that when I can Ashley
On 12/18/06, Ashley Moran <work at ashleymoran.me.uk> wrote:> Hi > > I just got bit by a misunderstanding about and_return. > > I''ve got this controller method parse_parameters that loops over > query string parameters and parses out vehicle registration dates. > We have to turn these into one of three bands (Jan-Feb, Mar-Aug, Sep- > Dec) so I wrote a method (registration_date_to_band_year_and_month) > takes a date and returns two return values, the year and month of the > band. > > I thought this would work: > > specify "should turn the provided registration date into a CAP > band" do > CapFutureResidual.should_receive > (:registration_date_to_band_year_and_month).with(Date.new(2003, 9, > 30)).and_return(2003, 9) > CapFutureResidual.should_receive > (:registration_date_to_band_year_and_month).with(Date.new(2005, 3, > 1)).and_return(2005, 3) > controller.parse_parameters( > { :capid26149 => "rd2003-09-30,mi40000,ft15", :capid30125 => > "rd2005-03-01,mi73825,ft42" } > ) > end > > But it doesn''t because and_return is setting up multiple method > calls, not multiple return values. > > I don''t imagine multiple return values are used that often, but they > can be handy. Would there be any use in another method, maybe > and_return_values or something to allow you to specify them? Since > they are possible in Ruby, it makes sense that you should be able to > specify them in RSpec. > > I got around it, of course, using an array return and the * expand > operator, but I avoid that when I can > > Ashleyhrm...when you return multiple values, isn''t it actually returning an array? irb(main):001:0> def foo; return 1, 2; end => nil irb(main):002:0> a = foo => [1, 2] irb(main):003:0> b, c = foo => [1, 2] irb(main):004:0> a => [1, 2] irb(main):005:0> b => 1 irb(main):006:0> c => 2 It''s just that Ruby is smart enough that you don''t need the [] in the return value. Also, doing multiple assignment works even if you explicitly return an array: irb(main):001:0> def foo; return [1, 2]; end => nil irb(main):002:0> a, b = foo => [1, 2] irb(main):003:0> a => 1 irb(main):004:0> b => 2 So it really should just be and_return([2005, 3]) Pat
Ashley Moran
2006-Dec-18 13:52 UTC
[rspec-users] should_receive and multiple return values
On 18 Dec 2006, at 12:31, Pat Maddox wrote:> So it really should just be and_return([2005, 3]) > > PatCool. I never realised that... if I''d changed my spec *first* like I''m supposed to I would have noticed it worked :) Thanks Ashley