現在日時をズラしたテストが実行できる「TimeHelpers(travel・travel_back・travel_to)」(Rails)

f:id:ryoutaku_jo:20190827234423p:plain

【結論】

ActiveSupportTimeHelpersでは、時間経過によって動作が変化する機能のテストを行う為のヘルパーメソッドが提供される

travelメソッドは、現在の日時を指定された日時の分だけ未来または過去の日時に変更する

travel_toメソッドは、直接指定した日時に現在の日時を変更する

【目次】

【本題】

TimeHelpersについて

RailsActiveSupportには、時間経過によって動作が変化する機能をテストする為のヘルパーがあります。

それがTimeHelpersです。

これにより、「有効期限の過ぎたクーポンが使えない」といったテストが実行できます。

RSpecへの導入方法

RSpecTimeHelpersを利用できる様にするには、まずrails_helper.rbにincludeする必要があります。

RSpec.configure do |config|
  #...
  config.include ActiveSupport::Testing::TimeHelpers
  #...
end

これによりTimeHelpersによって提供されるメソッドを利用する事が可能になります。

travelメソッド

travelメソッドは、Time.now・Date.today・DateTime.nowなどで呼び出される現在の時刻を、指定した任意の時間差に変更できます。

Time.current     
# => Sat, 09 Nov 2013 15:34:49 EST -05:00

travel 1.day
Time.current     
# => Sun, 10 Nov 2013 15:34:49 EST -05:00

変更された日時は、テストが終了した時点で元に戻ります。

もし部分的に現在日時を変更したい場合は、ブロックで対象のテストを囲めば、ブロック内の処理が完了すれば日時は元に戻ります。

Time.current 
# => Sat, 09 Nov 2013 15:34:49 EST -05:00

travel 1.day do
  User.create.created_at 
  # => Sun, 10 Nov 2013 15:34:49 EST -05:00
end

Time.current 
# => Sat, 09 Nov 2013 15:34:49 EST -05:00

または、travel_backメソッドを利用することで、元に戻すこともできます。

Time.current     
# => Sat, 09 Nov 2013 15:34:49 EST -05:00

travel 1.day
Time.current     
# => Sun, 10 Nov 2013 15:34:49 EST -05:00

travel_back
Time.current 
# => Sat, 09 Nov 2013 15:34:49 EST -05:00

travel_toメソッド

travelメソッドは、現在日時からの時間差で変更する日時を指定します。

対して、travel_toメソッドは、直接変更する日時を指定します。

Time.current     
# => Sat, 09 Nov 2013 15:34:49 EST -05:00

travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
Time.current     
# => Wed, 24 Nov 2004 01:04:44 EST -05:00

DateTime.current 
# => Wed, 24 Nov 2004 01:04:44 -0500

変更された日時は、テストが終了した時点で元に戻ります。

もし部分的に現在日時を変更したい場合は、travelメソッドと同様、ブロックで対象テストを囲うか、travel_backメソッドを利用します。

参考情報

ActiveSupport::Testing::TimeHelpers

Rails テスティングガイド - Rails ガイド

RSpec で安全に Timecop する - Qiita

《今日の学習進捗(3年以内に10000時間に向けて)》

・テストコードの拡充
Campaignの開始前後での挙動の違いをチェックするテストコードの実装を実施した。
当初、Campaignの期限を表すends_atのデータを書き換える方法を試したが、現在日時以前は選択不可というバリデーションの為、実装出来なかった。

最終的に、Rails4.1から導入されたテスト用のTimeHelpersのtravel_toメソッドを利用することで、ブロック内だけ現在日時の変更が出来た。
こちらの方がデータを書き換えるより、実際の処理を良く表しているので、時間経過のテストを行う際には有用だと感じた。

テストコードは、正しく対象をテスト出来ているという事が最重要だが、ドキュメントとしての役割も担っている為、その辺りも意識した実装を行いたいと改めて考え直す良いきっかけになった。

学習開始からの期間 :263日
今日までの合計時間:2482h
一日あたりの平均学習時間:9.5h
今日までに到達すべき目標時間:2402h
目標との解離:80h
「10,000時間」まで、

残り・・・「7518時間!」