【Rails】springでRSpecを起動したいがconfig/environments/test.rbにconfig.cache_classesの記述が見当たらない

Rails APIモードでspringを使ってRSpecを起動しようとしたんですが、config.cache_classesの設定の仕方がわからずハマったため、備忘録としてまとめます。

バージョン

  • Ruby 3.2.2
  • Rails 7.1.2

記事の信頼性

  • ぼくは独学で未経験から従業員300名以上の自社開発企業へ転職しました。
  • 実務ではVue.jsとRailsを毎日書いています。
  • 初心者や駆け出しエンジニアがつまづくポイントも身をもってよく理解しています。
目次

問題とやったこと

RailsのAPIモードを使ってTODOアプリを作ろうとしていました。

実践的にやりたいと思い、springを使ってRSpecを起動させようと考えました。

そのためにやったことは以下のとおりです。

①Gemfile に gem を追加し bundle install を実行

次のように、Gemfile にrspec-railsspring-commands-rspecを追加し、bundle installを実行しました。

group :development, :test do
  gem 'rspec-rails', '~> 6.1.0'
end

group :development do
  gem 'spring-commands-rspec'
end

※ぼくはDocker環境を構築しているため、docker compose build --no-cacheも実行しています。

②RSpecを動かすために必要なファイルの作成と実行確認

次に、springをつかわずにRSpecが実行できることを確認しました。

todo-app % docker compose run --rm rails bundle exec rails g rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

todo-app % docker compose run --rm rails bundle exec rspec
[+] Running 1/0
 ✔ Container todo-app-db-1  Running                                                                                                                                  0.0s 
No examples found.

Finished in 0.00027 seconds (files took 0.06623 seconds to load)
0 examples, 0 failures

todo-app %

なのでRSpecの設定は問題なさそう。

③spring用のファイルを作成

続いてbundle exec spring binstub rspecコマンドで、spring用のファイルbin/rspecを作成します。

todo-app % docker compose run --rm rails bundle exec spring binstub rspec
* bin/spring: generated with Spring
* bin/rspec: generated with Spring
todo-app % ls bin/
bundle    docker-entrypoint    rails    rake    rspec    setup    spring

todo-app %

無事に作成できました。

④springを使ってRSpecを実行したところ、、、

これで設定完了と思い、springを使ってRSpecの実行を試みたところ、次のエラーが出ました、、。

todo-app % docker compose run --rm rails bin/rspec        
[+] Running 1/0
 ✔ Container todo-app-db-1  Running                                                                                                                                  0.0s 
/usr/local/bundle/gems/spring-4.1.3/lib/spring/application.rb:100:in `block in preload': Spring reloads, and therefore needs the application to have reloading enabled.
Please, set config.cache_classes to false in config/environments/test.rb.
 (RuntimeError)
...

todo-app %

エラーメッセージを元に調べたところ、config/environments/test.rbconfig.cache_classes = falseと設定すれば良さそうでした。

しかし、config/environment/test.rbにはconfig.cache_classesという設定が存在しておらず、どうしていいかわかりませんでした、、。

現状のconfig/environment/test.rbは次のとおりです。

require "active_support/core_ext/integer/time"

# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # While tests run files are not watched, reloading is not necessary.
  config.enable_reloading = false

  # Eager loading loads your entire application. When running a single test locally,
  # this is usually not necessary, and can slow down your test suite. However, it's
  # recommended that you enable it in continuous integration systems to ensure eager
  # loading is working properly before deploying your code.
  config.eager_load = ENV["CI"].present?

  # Configure public file server for tests with Cache-Control for performance.
  config.public_file_server.enabled = true
  config.public_file_server.headers = {
    "Cache-Control" => "public, max-age=#{1.hour.to_i}"
  }

  # Show full error reports and disable caching.
  config.consider_all_requests_local = true
  config.action_controller.perform_caching = false
  config.cache_store = :null_store

  # Render exception templates for rescuable exceptions and raise for other exceptions.
  config.action_dispatch.show_exceptions = :rescuable

  # Disable request forgery protection in test environment.
  config.action_controller.allow_forgery_protection = false

  # Store uploaded files on the local file system in a temporary directory.
  config.active_storage.service = :test

  config.action_mailer.perform_caching = false

  # Tell Action Mailer not to deliver emails to the real world.
  # The :test delivery method accumulates sent emails in the
  # ActionMailer::Base.deliveries array.
  config.action_mailer.delivery_method = :test

  # Print deprecation notices to the stderr.
  config.active_support.deprecation = :stderr

  # Raise exceptions for disallowed deprecations.
  config.active_support.disallowed_deprecation = :raise

  # Tell Active Support which deprecation messages to disallow.
  config.active_support.disallowed_deprecation_warnings = []

  # Raises error for missing translations.
  # config.i18n.raise_on_missing_translations = true

  # Annotate rendered view with file names.
  # config.action_view.annotate_rendered_view_with_filenames = true

  # Raise error when a before_action's only/except options reference missing actions
  config.action_controller.raise_on_missing_callback_actions = true
end

解決方法

結論として、Rails7.1以降ではconfig.cache_classesという記述は使われておらず、代わりにconfig.enable_reloadingが導入されていました。

config.enable_reloadingはデフォルトでtrueですが、これをfalseに変更すればRails7.1以前のconfig.cache_classes = falseと同じことが実現できます。

require "active_support/core_ext/integer/time"

# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # While tests run files are not watched, reloading is not necessary.
  config.enable_reloading = true  ← ここを false から true に変更!

  # Eager loading loads your entire application. When running a single test locally,
  # this is usually not necessary, and can slow down your test suite. However, it's
  # recommended that you enable it in continuous integration systems to ensure eager
  # loading is working properly before deploying your code.
  config.eager_load = ENV["CI"].present?

  # Configure public file server for tests with Cache-Control for performance.
  config.public_file_server.enabled = true
  config.public_file_server.headers = {
    "Cache-Control" => "public, max-age=#{1.hour.to_i}"
  }

  # Show full error reports and disable caching.
  config.consider_all_requests_local = true
  config.action_controller.perform_caching = false
  config.cache_store = :null_store

  # Render exception templates for rescuable exceptions and raise for other exceptions.
  config.action_dispatch.show_exceptions = :rescuable

  # Disable request forgery protection in test environment.
  config.action_controller.allow_forgery_protection = false

  # Store uploaded files on the local file system in a temporary directory.
  config.active_storage.service = :test

  config.action_mailer.perform_caching = false

  # Tell Action Mailer not to deliver emails to the real world.
  # The :test delivery method accumulates sent emails in the
  # ActionMailer::Base.deliveries array.
  config.action_mailer.delivery_method = :test

  # Print deprecation notices to the stderr.
  config.active_support.deprecation = :stderr

  # Raise exceptions for disallowed deprecations.
  config.active_support.disallowed_deprecation = :raise

  # Tell Active Support which deprecation messages to disallow.
  config.active_support.disallowed_deprecation_warnings = []

  # Raises error for missing translations.
  # config.i18n.raise_on_missing_translations = true

  # Annotate rendered view with file names.
  # config.action_view.annotate_rendered_view_with_filenames = true

  # Raise error when a before_action's only/except options reference missing actions
  config.action_controller.raise_on_missing_callback_actions = true
end

これで再度コマンドを実行してみると、、、

todo-app % docker compose run --rm rails bin/rspec
[+] Running 1/0
 ✔ Container todo-app-db-1  Running                                                                                                                                  0.0s 
Running via Spring preloader in process 17
No examples found.

Finished in 0.00036 seconds (files took 0.15969 seconds to load)
0 examples, 0 failures

todo-app % 

無事にRSpecが実行できました!

※Rails7.1以前の場合は、config.cache_classes = trueという記述がデフォルトで存在しているはずなので、それをfalseにすれば問題ありません。

おわりに

公式ドキュメントを精読したことで原因を特定できました。一次情報は大事ですね。

参考文献
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

未経験でSESから従業員300名以上の自社開発企業に転職しました。業務や個人開発で直面した問題や、転職・学習の経験を発信していきます。

コメント

コメントする

目次