Rails外でActiveSupportのtravel_toが使えない時の解決方法

前提条件

  • Rails外でActiveSupportを使用している
  • テストフレームワークにRspecを使用している

エラーについて

Railsではなくsinatraを使ったAPIを書いていて、時間停止の便利関数travel_toを呼び出そうと思ったら以下のようなエラーが出てActiveSupportに定義されているtravel_to関数が使えませんでした。

Failure/Error: config.include ActiveSupport::Testing::TimeHelpers

NameError:
  uninitialized constant ActiveSupport::Testing

      config.include ActiveSupport::Testing::TimeHelpers
# 一部の情報を省略しています
Failures:

  1) ...nilの場合にtrue
     Failure/Error: travel_to Time.zone.local(2022, 9, 26, 15, 0, 0)
     
     NoMethodError:
       undefined method `travel_to' for #<RSpec::ExampleGroups::ExportUserExport::Functions::Expired "...nilの場合にtrue" (./spec/.._spec.rb:477)>
     # ./spec////_spec.rb:474:in `block (4 levels) in <top (required)>'

解決方法

spec_helper.rbにて明示的にtime_helpersrequireしてRSpec.configureのブロック内でTimeHelpersincludeしたら使えるようになりました。

require 'rspec'
require 'active_support/time'
require 'active_support/time_with_zone'
require 'active_support/testing/time_helpers' # 追加

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
    config.include ActiveSupport::Testing::TimeHelpers # 追加
  end
end

問題なくtravel_toが呼び出せました。

RSpec.describe 'Sample', type: :model do
  it 'travel_toが使えること' do
    travel_to Time.zone.local(2022, 10, 8, 0, 0, 0)
    puts Time.zone.now
  end
end

# 2022-10-08 00:00:00 +0900
# Finished in 0.00395 seconds (files took 0.32573 seconds to load)
# 1 example, 0 failures

補足: 一括読み込みについて

active_supportrequireを限定的に記述しているのはcloud runでの実行を想定しており、読み込むデータを少しでも少なくするためです。試しに一括読み込みをしようと思いrequire 'active_record'と記述したところ、モジュールの読み込み時にエラーが出ました。

Failure/Error: config.include ActiveSupport::Testing::TimeHelpers

NameError:
  uninitialized constant ActiveSupport::Testing

      config.include ActiveSupport::Testing::TimeHelpers

一括読み込みにはrequire 'active_support'ではなく、require 'active_support/all'が使えるようですが、ActiveSupport::Testingは読み込まれていませんでした。

require "active_support"
require "active_support/time"
require "active_support/core_ext"

rails/all.rb at main · rails/rails · GitHub

なので、testing/time_helpersを使いたい場合は明示的にrequireが必要でした。testingにはallに変わるものもなさそうです。

github.com

www.okb-shelf.work

参考文献