Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factory not registered: "credit_card" #341

Closed
vassalloandrea opened this issue May 28, 2019 · 13 comments
Closed

Factory not registered: "credit_card" #341

vassalloandrea opened this issue May 28, 2019 · 13 comments

Comments

@vassalloandrea
Copy link

I'm using Solidus to build an e-commerce.
Updating factory_bot_rails from the version 4.11.1 to the latest 5.0.2 something broke.

Running the test locally, RSpec returns this error:

KeyError:
  Factory not registered: "credit_card"

In this case, I included the credit_card factory from Solidus and overrode it adding a cc_type.

My override: spec/factories/credit_card_factory.rb

# frozen_string_literal: true

require 'spree/testing_support/factories/credit_card_factory'

FactoryBot.modify do
  factory :credit_card, class: Spree::CreditCard do
    cc_type { 'Visa' }
  end
end

Solidus factory: here the link

# frozen_string_literal: true

FactoryBot.define do
  factory :credit_card, class: 'Spree::CreditCard' do
    verification_value { 123 }
    month { 12 }
    year { 1.year.from_now.year }
    number { '4111111111111111' }
    name { 'Spree Commerce' }
    association(:payment_method, factory: :credit_card_payment_method)
    association(:address)

    trait :failing do
      number { "0000000000000000" }
    end
  end
end

I tried to figure out without success.
For now, I blocked the version on the project to factory_bot_rails 4.11.1.

@delphaber
Copy link

+1

Same situation with solidus 2.9.1 and factory_bot_rails 5.0.2

@delphaber
Copy link

delphaber commented Aug 22, 2019

@vassalloandrea I think it's a "chicken and egg" problem. I fixed the problem by moving out the file where I use FactoryBot.modify from spec/factories into another folder which is not autorequired from factory_bot, like spec/modified_spree_factories, then I manually require all files inside this new folder:

Inside rails_helper.rb

require 'spree/testing_support/factories'
Dir[Rails.root.join('spec', 'modified_spree_factories', '**', '*.rb')].sort.each { |file| require file }

Hope it helps!

@composerinteralia
Copy link
Collaborator

composerinteralia commented Oct 5, 2019

This has to do with FactoryBot.reload not playing well with requires in the definitions. FactoryBot.reload wipes out all of the factory definitions (including the spree definitions), and then reloads any definition files it knows about using load. If the spree definitions have already been required, require is a no-op the second time around.

This has always been a problem when using spring, since spring triggers a FactoryBot.reload in its forked process. It worked in 4.11 without spring because the definitions were only ever loaded once (unless you manually called FactoryBot.reload). This broke in 5.0 because there was a bug causing us to reload the definitions twice. We fixed the double reloading in 1e55d45, so if you upgrade to >= 5.1.1 the problem should go away (assuming you don't use spring).

It would be nice if we could get this use case working with spring, but I think that would require changes on the solidus side. We have an official way of sharing factories in the README, but solidus is not sharing them like that. You could add something like:

    config.factory_bot.definition_file_paths.unshift(
      Gem::Specification.find_by_name("solidus_core").gem_dir +
      "/lib/spree/testing_support/factories/credit_card_factory"
    )

to your application config to let factory_bot handle reloading the definitions as necessary, but unfortunately you can't do that with the whole "/lib/spree/testing_support/factories" directory because some of the factories there require other factories. You would have to configure them in whatever order solidus expects.

Another approach would be to set config.factory_bot.definition_file_paths = [] so factory_bot_rails doesn't handle any of the definition loading at all and then manually require the files you want in the order you want them. (This is effectively what @delphaber did by moving things into a directory factory_bot_rails doesn't know about.)

I will probably close this issue, since factory_bot_rails is back to the old behavior, and we do have a documented way of sharing factories.

@delphaber
Copy link

Thank you very much for the explanation @composerinteralia !

@mikong
Copy link

mikong commented Oct 24, 2019

@composerinteralia , I'm getting the Factory not registered error in Rails 6, and I'm not using Solidus. I'm not using rspec, so it's just the default minitest that comes with Rails.

The factory is pretty simple and defined in test/factories.rb:

FactoryBot.define do
  sequence :email do |n|
    "user#{n}@example.com"
  end

  factory :user do
    email
    password { "password123" }
  end
end

Should I create a separate issue?

If I add FactoryBot.reload in test_helper.rb, I don't get the error:

class ActiveSupport::TestCase
  [... redacted ...]
  FactoryBot.reload
  include FactoryBot::Syntax::Methods
end

@composerinteralia
Copy link
Collaborator

@mikong If you don't have solidus anywhere in your Gemfile.lock then this is a separate issue. I don't see anything obviously wrong in your code. Could you provide a sample application that reproduces the problem?

@mikong
Copy link

mikong commented Oct 24, 2019

@composerinteralia The error isn't happening anymore in my application. I tried to replicate the error in a branch just after I added factory_bot_rails but it's also no longer happening. If I reproduce the error next time, I'll open a new issue with a link to a sample application. Thanks.

@composerinteralia
Copy link
Collaborator

Sounds good. Thanks!

I am going to close this issue for now for the reasons mentioned in #341 (comment).

@joecabezas
Copy link

This is still an issue in Rails 6, I had to add
FactoryBot.reload
after appending a new route in definition_file_paths array in my rails_helper.rb
that solved the issue for me

@tdak
Copy link

tdak commented Oct 9, 2020

Same here, rails 6, sometimes factories can't be found.
FactoryBot.reload suggestion solves the issue

@knittingarch
Copy link

knittingarch commented Oct 12, 2020

Ran into this issue just now. In implementing the above, I was able to get my factories to work in the console, but unable to run my specs. I discovered that adding config.include FactoryBot::Syntax::Methods to my rails_helper.rb solved the issue for me and my specs now run! I found the suggestion in this thread.

knittingarch added a commit to knittingarch/censorix that referenced this issue Oct 12, 2020
This commit adds the Article model, which belongs_to a Post.

In order to facilitate testing, factories were added.  Unfortunately,
there were [unrecognized factories], and it was necessary to add
`config.include FactoryBot::Syntax::Methods` to my `rails_helper`
config.

[unrecognized factories] thoughtbot/factory_bot_rails#341
knittingarch added a commit to knittingarch/censorix that referenced this issue Oct 12, 2020
This commit adds the Article model, which belongs_to a Post.

In order to facilitate testing, factories were added.  Unfortunately,
there were [unrecognized factories], and it was necessary to add
`config.include FactoryBot::Syntax::Methods` to my `rails_helper`
config.

[unrecognized factories] thoughtbot/factory_bot_rails#341
knittingarch added a commit to knittingarch/censorix that referenced this issue Oct 12, 2020
This commit adds the Article model, which belongs_to a Post.

In order to facilitate testing, factories were added.  Unfortunately,
there were [unrecognized factories], and it was necessary to add
`config.include FactoryBot::Syntax::Methods` to my `rails_helper`
config.

[unrecognized factories] thoughtbot/factory_bot_rails#341
knittingarch added a commit to knittingarch/censorix that referenced this issue Oct 12, 2020
This commit adds the Article model, which belongs_to a Post.

In order to facilitate testing, factories were added.  Unfortunately,
there were [unrecognized factories], and it was necessary to add
`config.include FactoryBot::Syntax::Methods` to my `rails_helper`
config.

[unrecognized factories] thoughtbot/factory_bot_rails#341
@minhtienvu
Copy link

minhtienvu commented Mar 14, 2022

This is still an issue in Rails 6, I had to add FactoryBot.reload after appending a new route in definition_file_paths array in my rails_helper.rb that solved the issue for me

Same here, rails 6, Factory not registered: "user"
FactoryBot.reload suggestion solves the issue

Thanks for supporting. It's worked for me <3

@aoyshi
Copy link

aoyshi commented Apr 19, 2023

Was stuck on the same issue for a while for rails 6.1.7.3 and factory_bot_rails 6.2.0 (not using Spring or Solidus). Turns out, I had the /factories folder in the wrong location, relative to the paths that FactoryBot was searching for loading. I did not need the explicit FactoryBot.reload code addition in rails_helper.rb or spec_helper.rb.

If you spin up rails c for your project and run FactoryBot.reload, you'll see the array of file paths that FactoryBot is looking for to find your factories. Mine was nested one level above all the paths, and I just had to move it so it complied with one of them and still made sense for my project structure.

matafc pushed a commit to degica/barcelona that referenced this issue May 25, 2023
Camelcase error with rails7 dependency upgrade
thoughtbot/factory_bot_rails#341

```NameError:
  uninitialized constant Barcelona::Network::RDSStack
  Did you mean?  Barcelona::Network::RdsStack```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants