Subscribed unsubscribe Subscribe Subscribe

to_travel は DateTime.now に対応してない

 RSpecで現在時刻に関連するテストをするときに、Rails4.1からはTimecopを使わなくても ActiveSupport::Testing::TimeHelpers の to_travel というメソッドを使って現在時刻を設定することができます。

 たとえば、下記のように現在時刻を返すメソッドがあるとします。

class Foo
  def now
    Time.now
  end
end

 正しく現在時刻を返しているかのテストは下記のように書けます。

travel_to Time.new(2014, 11, 24, 9, 30, 0) do
  foo = Foo.new
  expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
end

 travel_toで現在時刻を設定しているので、expectで評価するときに決まった時間を書いて比較できます。

 ですがもしnowメソッドでDateTime.nowを返していると、to_travelでは対応できません。

class Foo
  def now
    DateTime.now # <- to_travelで設定した時間ではなく現在時刻が返る
  end
end

 その場合にはやはりTimecopを使う必要があります。Gemfileには下記のようにgemを追加。

group :test do
  gem 'timecop'
end

 テストは下記のように記述します。

Timecop.freeze(Time.new(2014, 11, 24, 9, 30, 0)) do
  foo = Foo.new
  expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
end

 travel_to が対応しているのは Time.now と Date.today のみのようです。

 travel_to(date_or_time, &block)
 rails4.1からのtravel_toをrspecで使う