Search code examples
ruby-on-railsrubyrake

How to override Date.today when running rails tests?


I have some tests that were failing on specific dates, because someone wrote them to use Date.today. I want to reproduce the failures on previous select dates.

Is there a way to run rake test with an ENV variable that will override the system clock? So that calls to Date.today, Time.now, and 1.day.ago and 1.day.from_now will use the date I set?

Like, for example:

> DATE_TODAY='2017-01-04' rake test

Solution

  • For testing you can use timecop gem. It offers you two useful methods Timecop.freeze and Timecop.travel.

    For example, you can use freeze to statically set time in before hooks:

    describe 'your tests' do
      before do
        Timecop.freeze(Time.new(2017, 1, 4))
      end
    
      after do
        Timecop.return
      end
    
      it 'should do something' do
        sleep(10)
        Time.now # => 2017-01-04 00:00:00
      end
    end
    

    Or in a block:

    Timecop.freeze(Time.now - 3.months) do
      assert product.expired?
    end
    

    While with the travel method, you change the starting moment, but time is still passing by.

    Timecop.travel(Time.new(2017, 1, 4))
    sleep(10)
    Time.now # => 2017-01-04 00:00:10