[rspec-users] Stubbing Scopes

Justin Ko jko170 at gmail.com
Tue Feb 15 12:51:03 EST 2011


Your expectation (should_receive) is expecting "start_of_day", which
uses Time.zone. The actual "on_day" scope does
"day.to_time.beginning_of_day", which does not use any time zone.
Therefore, the arguments to in_interval are not the same as the
expectation. And because they are not the same, the mock does not get
set. They must be exactly the same, since you are using a specific
values.

You are not seeing a "the in_interval method was not called"
expectation ouput message because of the "includes_values" error. This
is because RSpec is comparing "result" with an array. This is because
Rails scopes return arrays, not strings (it is not returning a string
because the mock was never set).

Are you setting the time zone in a before block?

Here are two really nice gems for dealing with Time sensitive code:
https://github.com/jtrupiano/timecop
https://github.com/bebanjo/delorean

On Feb 15, 9:35 am, Christoph Schiessl <c... at proactive.cc> wrote:
> Hi!
>
> I'm trying to test the following (simplified) model:
>
> class Allocation < ActiveRecord::Base
>   scope :in_interval, (proc do |start_of_interval, end_of_interval|
>     params = {:s => start_of_interval, :e => end_of_interval}
>     where("(starts_at > :s AND starts_at < :e) OR (ends_at > :s AND ends_at < :e) OR (starts_at <= :s AND ends_at >= :e)", params)
>   end)
>
>   scope :on_day, (proc do |day|
>     day = day.to_time.beginning_of_day
>     in_interval(day, day + 1.day)
>   end)
>
>   # validations and other scopes...
> end
>
> I wrote a lot of specs for :in_interval - however testing :on_day is kind of problem. I don't want to duplicate any :in_interval specs - therefore I'm trying to stub :in_interval like this:
>
> let(:start_of_day) { Time.zone.now.beginning_of_day }
> it do
>   Allocation.should_receive(:in_interval).with(start_of_day, start_of_day + 1.day).and_return("result")
>
>   # working assertion - the :in_interval stub seems to get called as expected:
>   # Allocation.on_day(start_of_day + 3.hours)
>
>   # failing assertion:
>   Allocation.on_day(start_of_day + 3.hours).should == "result"
> end
>
> RSpec Output:
>
>   Failure/Error: Allocation.on_day(start_of_day + 3.hours).should == "result"
>   NoMethodError:
>     undefined method `includes_values' for "result":String
>
> I'm using Rails 3.0.4 and RSpec 2.5 (latest versions).
>
> Best regards,
> Christoph Schiessl
> _______________________________________________
> rspec-users mailing list
> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users


More information about the rspec-users mailing list