Rails FactoryGirl inside app in development env
Asked Answered
F

2

4

I'm trying to use FactoryGirl gem inside my App in development mode (it's for mailer tests more) with rails_email_preview gem.

It works but only on initial page load, after reloading/refreshing the page I get following error:

Factory not registered: order

where order is name of factory.

Here is my code (it is a dummy app for my Rails Engine):

spec/dummy/app/mailer_previews/mymodule/order_mailer_preview.rb

Dir[Mymodule::Core::Engine.root.join('spec', 'factories', '*')].each do |f|
  require_dependency f
end

module Mymodule
class OrderMailerPreview
  def confirmation_email

    o = FactoryGirl.create(:order)

    OrderMailer.confirmation_email(o)
  end
end
end

Of course my factories works without any problem in test environment.

Any help would be appreciated.

EDIT:

p FactoryGirl.factories

returns (after page reload)

#<FactoryGirl::Registry:0x007ff2c9dd29d0 @name="Factory", @items={}>
Fatimafatimah answered 1/5, 2016 at 10:3 Comment(0)
F
0

It turns out that my issue was connected with Devise gem. I have code in my initializer which clears factories on each reload because of devise issue (described here). This code runs only when there are some factories, so not on the first request.

The solution was to change my config/initializers/devise.rb file from:

ActionDispatch::Callbacks.after do
  # Reload the factories
  return unless (Rails.env.development? || Rails.env.test?)

  unless FactoryGirl.factories.blank? # first init will load factories, this should only run on subsequent reloads
    FactoryGirl.factories.clear
    FactoryGirl.find_definitions
  end
end

to:

ActionDispatch::Callbacks.before do
  # Reload the factories
  return unless (Rails.env.development? || Rails.env.test?)

  FactoryGirl.definition_file_paths = [Mymodule::Core::Engine.root.join('spec', 'factories')]

  # first init will load factories, this should only run on subsequent reloads
  unless FactoryGirl.factories.blank?
    FactoryGirl.factories.clear
    FactoryGirl.sequences.clear
    FactoryGirl.find_definitions
  end
end

Note: before instead of after callback and custom FactoryGirl.definition_file_paths definition before find_definitions is executed.

Each time I try to use after hook I get Devise error on first call.

Fatimafatimah answered 3/5, 2016 at 11:49 Comment(0)
T
0

You'll need to call FactoryGirl.find_definitions to load factory girl in development.

require 'factory_girl'
FactoryGirl.find_definitions

Should do the trick.

Tartlet answered 1/5, 2016 at 11:27 Comment(1)
I've tried it but with no luck. Still it works after initial load and breaks on reload with Factory no registered error.Fatimafatimah
F
0

It turns out that my issue was connected with Devise gem. I have code in my initializer which clears factories on each reload because of devise issue (described here). This code runs only when there are some factories, so not on the first request.

The solution was to change my config/initializers/devise.rb file from:

ActionDispatch::Callbacks.after do
  # Reload the factories
  return unless (Rails.env.development? || Rails.env.test?)

  unless FactoryGirl.factories.blank? # first init will load factories, this should only run on subsequent reloads
    FactoryGirl.factories.clear
    FactoryGirl.find_definitions
  end
end

to:

ActionDispatch::Callbacks.before do
  # Reload the factories
  return unless (Rails.env.development? || Rails.env.test?)

  FactoryGirl.definition_file_paths = [Mymodule::Core::Engine.root.join('spec', 'factories')]

  # first init will load factories, this should only run on subsequent reloads
  unless FactoryGirl.factories.blank?
    FactoryGirl.factories.clear
    FactoryGirl.sequences.clear
    FactoryGirl.find_definitions
  end
end

Note: before instead of after callback and custom FactoryGirl.definition_file_paths definition before find_definitions is executed.

Each time I try to use after hook I get Devise error on first call.

Fatimafatimah answered 3/5, 2016 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.