При розробці тестів в Rails, якщо ви використовуєте FactoryBot
для створення фікстур для моделей, може виникнути ситуація, коли тест не може знайти потрібну фабрику. Ось приклад помилки, яку можна побачити:
...FF
Failures:
1) Deed default values has a default finished value of false
Failure/Error: let(:user) { create(:user) }
KeyError:
Factory not registered: "user"
# ./spec/models/deed_spec.rb:4:in `block (2 levels) in <top (required)>'
# ./spec/models/deed_spec.rb:12:in `block (3 levels) in <top (required)>'
# ./spec/models/deed_spec.rb:15:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# KeyError:
# key not found: "user"
# ./spec/models/deed_spec.rb:4:in `block (2 levels) in <top (required)>'
2) Deed#completed? returns true when the deed is finished
Failure/Error: let(:user) { create(:user) }
KeyError:
Factory not registered: "user"
# ./spec/models/deed_spec.rb:4:in `block (2 levels) in <top (required)>'
# ./spec/models/deed_spec.rb:20:in `block (3 levels) in <top (required)>'
# ./spec/models/deed_spec.rb:23:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# KeyError:
# key not found: "user"
# ./spec/models/deed_spec.rb:4:in `block (2 levels) in <top (required)>'
Опис проблеми
Це означає, що ваша фабрика для моделі user
не була знайдена в FactoryBot
. Це може статися через кілька причин, але найбільш поширена проблема полягає в тому, що FactoryBot
не може знайти папку, в якій зберігаються ваші фабрики.
У даному випадку, при виконанні команди:
time-tracker2(dev)> FactoryBot.find_definitions
=> ["/home/ruby/everything/projects/time_counters/shopify/time-counter/custom/factories"]
Але це не той шлях, де повинні бути збережені фабрики. Ваші фабрики зазвичай знаходяться в директорії spec/factories
, але FactoryBot
не знайшов їх у цьому шляху.
Перевірка шляху до фабрик
Щоб перевірити, де саме FactoryBot
шукає фабрики, скористайтеся командою:
FactoryBot.find_definitions
Вона виведе шляхи до всіх директорій, де FactoryBot
намагається знайти фабрики.
Рішення проблеми
Щоб виправити цю проблему, потрібно вказати правильний шлях до директорії, де зберігаються ваші фабрики. Для цього потрібно налаштувати FactoryBot
так, щоб він шукав фабрики в каталозі spec/factories
.
Для цього додайте наступне налаштування в файл spec/rails_helper.rb
:
#spec/rails_helper.rb
FactoryBot.definition_file_paths = [Rails.root.join('spec/factories')]
FactoryBot.find_definitions
RSpec.configure do |config|
...
end
Це вказує FactoryBot
, що йому слід шукати фабрики в директорії spec/factories
замість іншого шляху, який був встановлений за замовчуванням.
Пояснення
FactoryBot.definition_file_paths
— це налаштування, яке визначає шляхи до файлів з фабриками. За замовчуваннямFactoryBot
може шукати в інших місцях, таких якcustom/factories
. Ми змінюємо його наspec/factories
, де зберігаються ваші фабрики.Rails.root.join('spec/factories')
— це спосіб отримати повний шлях до директоріїspec/factories
на основі кореня вашого Rails-проекту.FactoryBot.find_definitions
— цей метод потрібно викликати після того, як ви вказали новий шлях до фабрик. Він змуситьFactoryBot
завантажити всі фабрики з нової директорії.