Ashley Moran
2006-Dec-15 17:39 UTC
[rspec-users] Partial mock when a complex return value is required
Hi I''ve come up with a problem using RSpec on a model class in my rails app. I wanted to test that some data was being cached for some calculations, so rather than do state-based testing I tried to specify that the method that fetches the data should NOT be called when I call the calculate method. However in doing so I have to simulate the return value, which is about 27 ActiveRecord objects with about 7 parameters. The only way I could stop the spec failing (because the rest of the method depends on this return value) was to duplicate the code in the spec. Here is a cut-down version of my class: class CapDerivativeInRegistrationBand < SimpleDelegator ... def cap_future_residuals @cap_future_residuals ||= cap_future_residuals_for_registration_date(registration_year, registration_month) end def residual_value(request_mileage, request_term) ... cap_future_residuals.each do |r| ... end ... # LOADS of other stuff going on here that relies on stuff produced from the above loop ... end end And here is the offending spec: specify "should prefetch the future residuals" do TODO: ask rspec team about duplicating this logic to get a nice error message @derivatives_by_id[26149].should_not_receive (:cap_future_residuals_for_registration_date).and_return( CapFutureResidual.find_all_by_derivative_id_and_registration_year_and_re gistration_month(26149, 2003, 9) ) end Sorry for the car finance jargon!!! How can I get round this? Here is my attempt at an alternative spec - is this better or worse? specify "should prefetch the future residuals" do # TODO: get rid of evil state testing residuals = @derivatives_by_id[26149].instance_variable_get ("@cap_future_residuals") @derivatives_by_id[26149].cap_future_residuals.should_equal residuals end Thanks for any advice Ashley
David Chelimsky
2006-Dec-16 22:12 UTC
[rspec-users] Partial mock when a complex return value is required
On 12/15/06, Ashley Moran <work at ashleymoran.me.uk> wrote:> Hi > > I''ve come up with a problem using RSpec on a model class in my rails > app. I wanted to test that some data was being cached for some > calculations, so rather than do state-based testing I tried to > specify that the method that fetches the data should NOT be called > when I call the calculate method. However in doing so I have to > simulate the return value, which is about 27 ActiveRecord objects > with about 7 parameters. The only way I could stop the spec failing > (because the rest of the method depends on this return value) was to > duplicate the code in the spec.This is confusing to me. You say you DON''T want the method called, but its return value is important to the rest of the method. Please explain.> > > Here is a cut-down version of my class: > > class CapDerivativeInRegistrationBand < SimpleDelegator > ... > > def cap_future_residuals > @cap_future_residuals ||> cap_future_residuals_for_registration_date(registration_year, > registration_month) > end > > def residual_value(request_mileage, request_term) > ... > > cap_future_residuals.each do |r| > ... > end > > ... > # LOADS of other stuff going on here that relies on stuff > produced from the above loop > ... > end > end > > > And here is the offending spec: > > specify "should prefetch the future residuals" do > TODO: ask rspec team about duplicating this logic to get a nice > error message > @derivatives_by_id[26149].should_not_receive > (:cap_future_residuals_for_registration_date).and_return( > > CapFutureResidual.find_all_by_derivative_id_and_registration_year_and_re > gistration_month(26149, 2003, 9) > ) > end > > Sorry for the car finance jargon!!! > > How can I get round this? Here is my attempt at an alternative spec > - is this better or worse? > > specify "should prefetch the future residuals" do > # TODO: get rid of evil state testing > residuals = @derivatives_by_id[26149].instance_variable_get > ("@cap_future_residuals") > @derivatives_by_id[26149].cap_future_residuals.should_equal > residuals > end > > Thanks for any advice > Ashley > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Ashley Moran
2006-Dec-17 13:19 UTC
[rspec-users] Partial mock when a complex return value is required
On Dec 16, 2006, at 10:12 pm, David Chelimsky wrote:> This is confusing to me. You say you DON''T want the method called, but > its return value is important to the rest of the method. Please > explain.When you put it like that, I got confused too lol. I just tried it again without the extra return value and it works fine (which makes sense). I must have assumed that method was being called some other way... because when I wrote the spec it gave me an error about a nil object, but then the should_not_receive passed when I put the return value in. God only knows what I wrote to do that... Sorry for the noise! Ashley
David Chelimsky
2006-Dec-17 14:03 UTC
[rspec-users] Partial mock when a complex return value is required
On 12/17/06, Ashley Moran <work at ashleymoran.me.uk> wrote:> > On Dec 16, 2006, at 10:12 pm, David Chelimsky wrote: > > > This is confusing to me. You say you DON''T want the method called, but > > its return value is important to the rest of the method. Please > > explain. > > > When you put it like that, I got confused too lol. I just tried it > again without the extra return value and it works fine (which makes > sense). I must have assumed that method was being called some other > way... because when I wrote the spec it gave me an error about a nil > object, but then the should_not_receive passed when I put the return > value in. God only knows what I wrote to do that... > > Sorry for the noise!No worries. Glad it''s resolved. Cheers, David> > Ashley > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >