So... I settled for testing with message expectations without return values. Guess that's good enough for now. Thank you anyway!
Best regards, Christoph Schiessl On Feb 15, 2011, at 21:34 , Justin Ko wrote: > > > On Feb 15, 11:14 am, Christoph Schiessl <c...@proactive.cc> 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 <c...@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...@rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users >>> _______________________________________________ >>> rspec-users mailing list >>> rspec-us...@rubyforge.org >>> http://rubyforge.org/mailman/listinfo/rspec-users >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us...@rubyforge.orghttp://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 > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users