How to fake Time.now?
I really like the Timecop library. You can do time warps in block form (just like time-warp):
Timecop.travel(6.days.ago) do @model = TimeSensitiveMode.newendassert @model.times_up!
(Yes, you can nest block-form time travel.)
You can also do declarative time travel:
class MyTest < Test::Unit::TestCase def setup Timecop.travel(...) end def teardown Timecop.return endend
I have some cucumber helpers for Timecop here. They let you do things like:
Given it is currently January 24, 2008And I go to the new post pageAnd I fill in "title" with "An old post"And I fill in "body" with "..."And I press "Submit"And we jump in our Delorean and return to the presentWhen I go to the home pageI should not see "An old post"
Personally I prefer to make the clock injectable, like so:
def hello(clock=Time) puts "the time is now: #{clock.now}"end
Or:
class MyClass attr_writer :clock def initialize @clock = Time end def hello puts "the time is now: #{@clock.now}" endend
However, many prefer to use a mocking/stubbing library. In RSpec/flexmock you can use:
Time.stub!(:now).and_return(Time.mktime(1970,1,1))
Or in Mocha:
Time.stubs(:now).returns(Time.mktime(1970,1,1))
I'm using RSpec and I did this: Time.stub!(:now).and_return(2.days.ago) before I call Time.now. In that way I'm able to control the time I used for that particular test case