Jay,

I don't know about Mocha, but you have to be a bit careful about  
replacing Time.now because the test timings depend on it. The way I  
do it is as follows. First, I've got a little plugin that includes this:

   class Time
     @@now = nil

     def self.now=(time)
       @@now = time
     end

     def self.forced_now #:nodoc:
       @@now || unforced_now
     end

     class << self
       alias_method :unforced_now, :now
       alias_method :now, :forced_now
     end
   end

and then in my test helper:

   def at_time(time)
     time = Time.parse(time + ' UTC') unless time.instance_of?(Time)
     Time.now = time
     begin
       yield
     ensure
       Time.now = nil
     end
   end

That lets me do something like this in a test:

   def test_whatever
     at_time("Jan 1 2001") do
       # Tests go in here.
     end
   end

Hope that helps!

Cheers,

Pete Yandell


On 06/09/2006, at 7:25 AM, Jay Levitt wrote:

> Mocha seems a great way to stub Time.now for testing expiration  
> dates, etc.
> with rspec.  I can get it to stub a single time easily:
>
>   Time.stubs(:now).returns(Time.at(1))
>
> but what I'd really like to do is do that multiple times during a  
> test:
>
>   specify "with an expired cookie should return nil"
>     Time.stubs(:now).returns(Time.parse("Jan 1 2001"))
>     louie.login
>     cookie = louie.remember_me
>
>     Time.stubs(:now).returns(Time.parse("Oct 1 2001"))
>     louie.login_with_cookie(cookie).should_be_nil
>   end
>
> However, only the first stubs call has any effect.  I've tried  
> stubbing it
> to a FakeTime object:
>
>   Time.stubs(:now).returns(FakeTime.now)
>
> but it only looks at the value of FakeTime.now when the stub is  
> created.
> Is there a way using Mocha/Stubba to stub a routine and have it call
> another for the return value?  I've tried creating procs/lambdas,  
> but I
> must be doing something wrong - I get an infinite recursion.
>
> Jay Levitt
>