Skip to content

Commit

Permalink
Add option to lazy load factory definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
quadule committed Jan 7, 2025
1 parent 346e3c7 commit f18edf4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ class MyEngine < ::Rails::Engine
end
```

If your application has a large number of factories, you may want to enable
lazy loading to speed up boot time:

```rb
config.factory_bot.lazy_load_definitions = true
```

With lazy loading of definitions enabled, `FactoryBot.factories` will appear
empty after booting the application. All factory definitions will be loaded
when any factory is first accessed by name.

You can also disable automatic factory definition loading entirely by
using an empty array:

Expand Down
33 changes: 33 additions & 0 deletions features/load_definitions.feature
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,36 @@ Feature: automatically load factory definitions
"""
When I run `bundle exec rake test` with a clean environment
Then the output should contain "2 assertions, 0 failures, 0 errors"

Scenario: use lazy loading of factory definitions
When I configure the factories as:
"""
config.factory_bot.lazy_load_definitions = true
"""
When I write to "test/factories.rb" with:
"""
FactoryBot.define do
factory :user do
name { "Frank" }
end
end
"""
When I write to "test/unit/user_test.rb" with:
"""
require 'test_helper'
class UserTest < ActiveSupport::TestCase
test "use lazy loaded factory" do
assert FactoryBot.factories.none?
refute FactoryBot.factories.registered?(:user)
user = FactoryBot.create(:user)
assert_equal 'Frank', user.name
assert FactoryBot.factories.any?
assert FactoryBot.factories.registered?(:user)
end
end
"""
When I run `bundle exec rake test` with a clean environment
Then the output should contain "5 assertions, 0 failures, 0 errors"
10 changes: 10 additions & 0 deletions lib/factory_bot_rails/lazy_registry_find.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "factory_bot/registry"

module FactoryBotRails
module LazyRegistryFind
def find(*)
FactoryBot.find_definitions unless FactoryBot.factories.any?
super
end
end
end
9 changes: 8 additions & 1 deletion lib/factory_bot_rails/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module FactoryBotRails
class Railtie < Rails::Railtie
config.factory_bot = ActiveSupport::OrderedOptions.new
config.factory_bot.definition_file_paths = FactoryBot.definition_file_paths
config.factory_bot.lazy_load_definitions = false
config.factory_bot.validator = FactoryBotRails::FactoryValidator.new

initializer "factory_bot.set_fixture_replacement" do
Expand All @@ -21,7 +22,13 @@ class Railtie < Rails::Railtie
end

config.after_initialize do |app|
FactoryBot.find_definitions
if app.config.factory_bot.lazy_load_definitions && !app.config.eager_load
require "factory_bot_rails/lazy_registry_find"
FactoryBot::Registry.prepend FactoryBotRails::LazyRegistryFind
else
FactoryBot.find_definitions
end

Reloader.new(app).run
app.config.factory_bot.validator.run
end
Expand Down

0 comments on commit f18edf4

Please sign in to comment.