mirror of
https://github.com/thoughtbot/factory_bot_rails.git
synced 2022-11-09 11:49:18 -05:00
1e55d45bfb
Fixes #336 Alternate solution to #343 The initialization process looks like this: Rails runs all of the initializers 1. Run the ["factory_bot.set_factory_paths"][set_factory_paths] initializer 2. Run the ["factory_bot.register_reloader"][register_reloader] initializer, which sets up a [prepare callback][] 3. Run the [`:run_prepare_callbacks`][] initializer 4. This triggers the factory_bot [prepare callback][], which causes factory\_bot to [reload][] Rails runs `after_initialize` callbacks 1. [I18n initializes] 2. factory\_bot [reloads again][] as described in #334 The double reloading of factory_bot in this initialization is not ideal, but also shouldn't generally cause any problems on its own. The problems people are having in #336 come from the fact that I18n gets set up in an `after_initialize` callback, but factory_bot gets reloaded before the `after_initialize` callbacks are triggered. If the `FactoryBot.define` block references any code that uses I18n translations as it loads, that code will raise an error (references inside other factory_bot methods, or code that uses I18n translations inside of methods still works fine, since the whole Rails initialization process would be complete by the time any of that code runs). This commit changes step 4 above to avoid reloading factory_bot before the application has initialized. [set_factory_paths]:3815aae2b9/lib/factory_bot_rails/railtie.rb (L17-L19)
[register_reloader]:3815aae2b9/lib/factory_bot_rails/railtie.rb (L21-L23)
[prepare callback]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L34-L36 [`:run_prepare_callbacks`]: https://github.com/rails/rails/blob/5-2-stable/railties/lib/rails/application/finisher.rb#L62-L64 [reload]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L24-L26 [I18n initializes]:13e2102517/activesupport/lib/active_support/i18n_railtie.rb (L16-L20)
[reloads again]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/railtie.rb#L25-L27 Co-authored-by: Danny Garcia <dannygarcia.me@gmail.com>
107 lines
3.4 KiB
Gherkin
107 lines
3.4 KiB
Gherkin
Feature:
|
|
When using factory_bot_rails together with Spring
|
|
I want changes to my application to trigger the factory_bot_rails reloader
|
|
So that factory_bot_rails doesn't hold onto stale class references
|
|
|
|
Scenario: Editing a model without editing the factory
|
|
When I successfully run `bundle exec rails new testapp -m ../../features/support/rails_template`
|
|
And I cd to "testapp"
|
|
And I add "factory_bot_rails" from this project as a dependency
|
|
And I add "test-unit" as a dependency
|
|
And I run `bundle install` with a clean environment
|
|
And I write to "db/migrate/1_create_users.rb" with:
|
|
"""
|
|
migration_class =
|
|
if ActiveRecord::Migration.respond_to?(:[])
|
|
ActiveRecord::Migration[4.2]
|
|
else
|
|
ActiveRecord::Migration
|
|
end
|
|
|
|
class CreateUsers < migration_class
|
|
def self.up
|
|
create_table :users do |t|
|
|
t.string :name
|
|
end
|
|
end
|
|
end
|
|
"""
|
|
And I run `bundle exec rake db:migrate` with a clean environment
|
|
And I write to "app/models/user.rb" with:
|
|
"""
|
|
class User < ActiveRecord::Base
|
|
end
|
|
"""
|
|
And I write to "test/factories.rb" with:
|
|
"""
|
|
FactoryBot.define do
|
|
factory :author, class: User do
|
|
name { "Frank" }
|
|
end
|
|
end
|
|
"""
|
|
And I write to "test/unit/user_test.rb" with:
|
|
"""
|
|
require 'test_helper'
|
|
|
|
class UserTest < ActiveSupport::TestCase
|
|
test "use factory" do
|
|
author = FactoryBot.create(:author)
|
|
|
|
assert_equal author.class.object_id, User.object_id
|
|
end
|
|
end
|
|
"""
|
|
And I run `bundle binstubs bundler rake spring --force` with a clean environment
|
|
And I run `bin/spring binstub --all` with a clean environment
|
|
And I run `bin/rake test` with Spring enabled
|
|
And I append to "app/models/user.rb" with:
|
|
"""
|
|
# User model edited
|
|
"""
|
|
And I run `bin/rake test` with Spring enabled
|
|
And I run `spring stop` with a clean environment
|
|
Then the output should contain "1 runs, 1 assertions"
|
|
And the output should not contain "Failure:"
|
|
|
|
Scenario: Initializing the reloader with I18n support
|
|
When I successfully run `bundle exec rails new testapp -m ../../features/support/rails_template`
|
|
And I cd to "testapp"
|
|
And I add "factory_bot_rails" from this project as a dependency
|
|
And I add "test-unit" as a dependency
|
|
And I run `bundle install` with a clean environment
|
|
And I run `bundle exec rake db:migrate` with a clean environment
|
|
And I write to "app/models/user.rb" with:
|
|
"""
|
|
class User
|
|
TRANSLATION = I18n.translate("translation_key")
|
|
end
|
|
"""
|
|
And I write to "config/locales/en.yml" with:
|
|
"""
|
|
en:
|
|
translation_key: "translation_value"
|
|
"""
|
|
And I write to "test/factories.rb" with:
|
|
"""
|
|
FactoryBot.define do
|
|
factory :user do
|
|
User::TRANSLATION
|
|
end
|
|
end
|
|
"""
|
|
And I write to "test/unit/user_test.rb" with:
|
|
"""
|
|
require 'test_helper'
|
|
|
|
class UserTest < ActiveSupport::TestCase
|
|
test "use factory" do
|
|
user = FactoryBot.build(:user)
|
|
|
|
assert_equal "translation_value", User::TRANSLATION
|
|
end
|
|
end
|
|
"""
|
|
And I run `bundle exec rake test` with a clean environment
|
|
Then the output should contain "1 runs, 1 assertions"
|
|
And the output should not contain "Failure:"
|