[rspec-users] Partial mock when a complex return value is required

Ashley Moran work at ashleymoran.me.uk
Fri Dec 15 12:39:19 EST 2006


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


More information about the rspec-users mailing list