Skip to content

Commit 3c76e51

Browse files
committed
Add option to lazy load factory definitions
1 parent 83109a5 commit 3c76e51

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ class MyEngine < ::Rails::Engine
7777
end
7878
```
7979

80+
If your application has a large number of factories, you may want to enable
81+
lazy loading to speed up boot time:
82+
83+
```rb
84+
config.factory_bot.lazy_load_definitions = true
85+
```
86+
87+
With lazy loading of definitions enabled, `FactoryBot.factories` will appear
88+
empty after booting the application. All factory definitions will be loaded
89+
when any factory is first accessed by name.
90+
8091
You can also disable automatic factory definition loading entirely by
8192
using an empty array:
8293

features/load_definitions.feature

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,36 @@ Feature: automatically load factory definitions
197197
"""
198198
When I run `bundle exec rake test` with a clean environment
199199
Then the output should contain "2 assertions, 0 failures, 0 errors"
200+
201+
Scenario: use lazy loading of factory definitions
202+
When I configure the factories as:
203+
"""
204+
config.factory_bot.lazy_load_definitions = true
205+
"""
206+
When I write to "test/factories.rb" with:
207+
"""
208+
FactoryBot.define do
209+
factory :user do
210+
name { "Frank" }
211+
end
212+
end
213+
"""
214+
When I write to "test/unit/user_test.rb" with:
215+
"""
216+
require 'test_helper'
217+
218+
class UserTest < ActiveSupport::TestCase
219+
test "use lazy loaded factory" do
220+
assert FactoryBot.factories.none?
221+
refute FactoryBot.factories.registered?(:user)
222+
223+
user = FactoryBot.build(:user)
224+
assert_equal 'Frank', user.name
225+
226+
assert FactoryBot.factories.any?
227+
assert FactoryBot.factories.registered?(:user)
228+
end
229+
end
230+
"""
231+
When I run `bundle exec rake test` with a clean environment
232+
Then the output should contain "5 assertions, 0 failures, 0 errors"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
require "factory_bot/registry"
2+
3+
module FactoryBotRails
4+
module LazyRegistryFind
5+
def self.find_definitions_once
6+
return if defined?(@definitions_loaded)
7+
FactoryBot.find_definitions
8+
@definitions_loaded = true
9+
end
10+
11+
def find(*)
12+
LazyRegistryFind.find_definitions_once
13+
super
14+
end
15+
end
16+
end

lib/factory_bot_rails/railtie.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module FactoryBotRails
1111
class Railtie < Rails::Railtie
1212
config.factory_bot = ActiveSupport::OrderedOptions.new
1313
config.factory_bot.definition_file_paths = FactoryBot.definition_file_paths
14+
config.factory_bot.lazy_load_definitions = false
1415
config.factory_bot.validator = FactoryBotRails::FactoryValidator.new
1516
config.factory_bot.file_fixture_support = true
1617

@@ -39,7 +40,13 @@ class Railtie < Rails::Railtie
3940
end
4041

4142
config.after_initialize do |app|
42-
FactoryBot.find_definitions
43+
if app.config.factory_bot.lazy_load_definitions && !app.config.eager_load
44+
require "factory_bot_rails/lazy_registry_find"
45+
FactoryBot::Registry.prepend FactoryBotRails::LazyRegistryFind
46+
else
47+
FactoryBot.find_definitions
48+
end
49+
4350
Reloader.new(app).run
4451
app.config.factory_bot.validator.run
4552
end

0 commit comments

Comments
 (0)