この記事で伝えたいこと
KeyError: Factory not registered: ...
というFactoryBotのエラーが出てこの記事にたどり着いた方へ。
あなたが作っているアプリはRailsアプリではありませんか?
もしそうなら、Gemfileに以下のように書いていませんか?
# これは間違い!
gem 'factory_bot'
どちらもYesなら、以下のように factory_bot_rails を使うようにすることで KeyError: Factory not registered
が起こらなくなると思いますので、お試しください。
- gem 'factory_bot'
+ gem 'factory_bot_rails'
もっとくわしく
この記事を書いた経緯
RailsにFactoryBotを入れる場合、本来は factory_bot_rails を使うべきですが、factory_bot を使ってしまったことで KeyError: Factory not registered
が起こりました。
このエラーに対して当初は誤った対処をしてしまいましたが、有識者の方に教えていただいたことで正しい対処方法が分かりました。
そこで、もし私と同じようなルートを辿る方がいらしたら、この記事が役に立つといいなと思って書きました。
やりたかったこと
RailsアプリでFactoryBotを利用したい。
やったこと
- Gemfileに
gem 'factoy_bot'
を追加する 👈ここが間違い - ファクトリを作成する
- テストファイル(またはスペックファイル)を書く
※この時に私が使ったのはMinitestでしたが、RSpecでも同様の事象が発生することを確認しました - テスト(またはスペック)を実行する
発生したエラー
KeyError: Factory not registered: "user"
test/models/user_test.rb:8:in `block in <class:UserTest>'
rails test test/models/user_test.rb:7
KeyError:
Factory not registered: "user"
# ./spec/models/user_spec.rb:5:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# KeyError:
# key not found: "user"
# ./spec/models/user_spec.rb:5:in `block (2 levels) in <top (required)>'
誤った対処
テストでファクトリを呼び出す前に FactoryBot.reload
すると良いという情報にたどりつき、その情報が自分の状況に合ったものかよく確かめないまま真似しました。
確かに動くようになるものの、毎回リロードしないといけないなんて何だか変な気が…🤔
minitestの例
# これは間違い!
setup do
FactoryBot.reload
@user = create(:user)
end
RSpecの例
# これは間違い!
RSpec.configure do |config|
config.before(:all) do
FactoryBot.reload
end
end
正しい対処
Rails向けに作られたfactoy_bot_railsを使うようにすることで、FactoryBot.reload
がなくても動くようになりました。1
- gem 'factory_bot'
+ gem 'factory_bot_rails'
教訓
実はfactoy_botのREADMEには、しっかりこの事が書いてありました。
thoughtbot/factory_bot: A library for setting up Ruby objects as test data.
If you want to use factory_bot with Rails, see factory_bot_rails.
拙訳:もしあなたがRailsでfactory_botを使いたいなら、factory_bot_railsのページを見てください
gemにしても何にしても、誰かが作ってくれた仕組みを使わせてもらう時はREADMEの冒頭くらいは目を通しましょう、という事を身をもって理解できた出来事でした
最後に
この記事で書いた一連の流れは、フィヨルドブートキャンプの課題に取り組んでいる際にぶつかり、提出した課題をレビューしていただいたことで分かった事です。
今回レビューしてくださった @jnchito さん、ありがとうございます。
課題の方はまだ終わってないので引き続き取り組みます💪
フィヨルドブートキャンプよいとこ一度はおいで2
-
正確には、factoy_bot_railsがリロードなども含めてRailsでFactoryBotを使うために必要な部分の面倒を見てくれているので、一々自分で書く必要がなくなるということのようです ↩