如何在 运行 rails 测试时覆盖 Date.today?

How to override Date.today when running rails tests?

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

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

喜欢,例如:

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

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

比如可以使用freeze静态设置时间在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

或在块中:

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 4.1 开始,您可以做到

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

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