自転車とプログラミング

元自転車メーカーのマーケター、今は自社開発企業に勤めるエンジニアが主にプログラミングの話を書きます。

Gemfileのrequire: falseによるFactory_bot_railsの初期化エラーと格闘した話

こんにちは、東京で駆け出しエンジニアをしているwatanabeです。

現在、Railsで作った自作サービス「MAAKS」の自動テストをRails標準のminitestからRSpecに移行させています。

手始めにPOROでモデルテストを書いて、Factoryを使ってデータつくるようにしようか〜と作業していたところ次のような例外に遭遇しました。

Failures:

  1) Spot spotの所有者が.owned_byでわかる
     Failure/Error: user_owned_spot = FactoryBot.create(:admin_user)
     
     NameError:
       uninitialized constant FactoryBot
     # ./spec/models/spot_spec.rb:7:in `block (2 levels) in <top (required)>'

状況としてはかなり簡易なモデルテストをやるために、テスト内でモデルのインスタンスを作る処理を書いたところをファクトリに移管するべくGemをインストールしてファクトリを書いてテストを書き換えて実行したところでした。

FactoryBotが初期化できていないっぽいようなメッセージがではありますが、例外のメッセージがかなりざっくりしているので、初見だと原因はわかりません。 コードを修正したり、コンソールを動かしたり、gemのREADMEを再読したり右往左往してました。

最終的にはGemfileの記述が原因でテスト実行時にFactoryBotが読み込まれていない状態になっていたことがわかりました。 Gemfileは↓のように書いていました。

ここで記述した require: false が悪さをしていたのですが、これは該当する環境実行時に記述したgemの自動読み込みを停止して、必要な呼び出しが生じた際に初めて読み込まれるようにする機能です。

開発サーバを動かしたりテストを実行するのを早くするために書いていたのですが、これのせいでFactoryBotが読み込まれておらず、呼び出し時に例外が発生してしまっていました。また、RSpec側もGemfileをデフォの記述していればFacotry_botと連携が取れるため、特に起動時に読み込まれなかった場合のフォローがなかったことも例外の要因ですかね。

対応としては require: falseの指定を削除するか、require: falseを維持しつつ spec/rails_helper.rbでFacotry_botをrequireしてあげると解決します。

以上、2時間対応した供養として記事にします。みなさんはお気をつけて。