【问题标题】:How to override Date.today when running rails tests?运行 Rails 测试时如何覆盖 Date.today?
【发布时间】:2017-01-04 13:59:26
【问题描述】:

我有一些测试在特定日期失败,因为有人写它们使用Date.today。我想重现之前选择日期的失败。

有没有办法使用覆盖系统时钟的 ENV 变量运行 rake 测试?那么对Date.todayTime.now1.day.ago1.day.from_now 的调用将使用我设置的日期?

例如:

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

【问题讨论】:

    标签: ruby-on-rails ruby rake


    【解决方案1】:

    对于测试,您可以使用timecop gem。 它为您提供了两种有用的方法Timecop.freezeTimecop.travel

    例如,您可以使用freeze挂钩前中静态设置时间:

    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
    

    或在中:

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

    虽然使用travel 方法,您更改了开始时刻,但时间仍在流逝

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

    【讨论】:

    • 如果您使用的是 Rails v4.1+,那么现在有内置的 TimeHelpers - 可能(至少,对于像这样的简单场景)使得合并不需要第三方库,例如 aTimeCop
    • @TomLord 请发布答案。我使用它,它很棒。
    • @TomLord 请注意,Rails 5 之前的 time_travel 不支持 DateTime.now。
    • 我相信这个答案(以及 Timecop 本身)已经过时了,因为 Rails 有 TimeHelpers。我会推荐the other answer
    【解决方案2】:

    从 Rails 4.1 开始,您可以这样做

    travel_to Time.new(2004, 11, 24, 01, 04, 44)
    

    完整的 API 文档在这里:http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html

    【讨论】:

    • 谢谢,很高兴知道这一点,尽管我使用的是 Rails 4
    猜你喜欢
    • 1970-01-01
    • 2019-09-10
    • 2016-11-09
    • 1970-01-01
    • 2011-03-19
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多