[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