On Feb 15, 11:14 am, Christoph Schiessl <[email protected]> wrote:
> Thanks for your suggestion Justin, but I don't believe that the problem is
> time zone related. Time objects usually don't "loose" their Time Zone when
> performing operations on them. Here's an example for illustration:
>
> $ rails console
> Loading development environment (Rails 3.0.4)
> ruby-1.8.7-p330 :001 > Time.zone.name
> => "Vienna"
> ruby-1.8.7-p330 :002 > t = Time.zone.now.beginning_of_month
> => Tue, 01 Feb 2011 00:00:00 CET +01:00
> ruby-1.8.7-p330 :003 > t += 3.hours
> => Tue, 01 Feb 2011 03:00:00 CET +01:00
> ruby-1.8.7-p330 :004 > t.beginning_of_day
> => Tue, 01 Feb 2011 00:00:00 CET +01:00
>
> If the should_receive arguments and actual arguments wouldn't be the same,
> then I would expect both examples below to fail.
>
> context ".on_day" do
> let(:start_of_day) { Time.zone.now.beginning_of_day }
> before { Interval.should_receive(:in_interval).with(start_of_day,
> start_of_day + 1.day).and_return("result") }
> # (1) Passing example:
> it { Interval.on_day(start_of_day + 3.hours) }
> # (2) Failing example:
> it { Interval.on_day(start_of_day + 3.hours).should == "result" }
> end
>
> However, (1) is passing and (2) is failing. Output as before:
>
> >> Failure/Error: Allocation.on_day(start_of_day + 3.hours).should ==
> >> "result"
> >> NoMethodError:
> >> undefined method `includes_values' for "result":String
>
> Any ideas?
>
> Best regards,
> Christoph Schiessl
>
> On Feb 15, 2011, at 18:51 , Justin Ko wrote:
>
>
>
>
>
> > 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 <[email protected]> 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
> >> [email protected]http://rubyforge.org/mailman/listinfo/rspec-users
> > _______________________________________________
> > rspec-users mailing list
> > [email protected]
> >http://rubyforge.org/mailman/listinfo/rspec-users
>
> _______________________________________________
> rspec-users mailing list
> [email protected]http://rubyforge.org/mailman/listinfo/rspec-users
Maybe because the scope is being called within a scope, it is wrapping
it in an array: ["results"]
Either way, report back what this code returns: it { raise
Interval.on_day(start_of_day + 3.hours).inspect }
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users