Fixing the FactoryBot configuration #4014
elia
started this conversation in
Show and tell
Replies: 1 comment
-
Fixed an annoyance we encountered with deprecation warnings from |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
We've been doing FactoryBot updates on a number of apps internally at @nebulab, so we'd like to share our process for doing that, in the hope it will be helpful for others.
Overview
The way Solidus was loading FactoryBot factories up until v2.11 was a hack that
worked against Rails reloading and made them substantially incompatible with Spring
and other tools, in addition to being at odds with the installation instruction that
could be found in the FactoryBot and FactoryBotRails respective READMEs.
What's wrong with the previous setup?
The basic loading mechanism for factories is still loading the factory file with either
require
orload
. Over time FactoryBot moved to collecting the paths were factoriesare defined and loading them in bulk when
FactoryBot.find_definitions
is called. Solidusitself, many of its extensions, and most apps ended up in a mix of calling both
require
and
find_definitions
.Usually this was the result of trying to apply FactoryBot's instructions and bumping into some
issue with the loading sequence, or weird errors that ended up being resolved only by a
complete app restart (or
spring stop
, etc.).How a loading factories in the wrong order can break your app?
One of the main issues with Solidus factories used inside your Rails application is that of
factories modifying existing ones. In fact if you add an attribute to, say,
Spree::User
youalso probably need to update its factory with code that looks more ore less like this:
spec/factories/users.rb
This kind of factory strictly requires the
:user
factory defined by solidus in[solidus-core-root]/lib/spree/testing_support/factories/user_factory.rb
to be loaded first.Even worse the situation in which your application needs to modify a factory that is defined in
Solidus and then modified by one or more extensions.
The solution (in 2 easy steps)
Give all of that we needed a solution that could give a way forward without wreaking havoc in all
existing apps and extensions. For this reason doing nothing will just work, and show some deprecations,
but we strongly encourage the upgrade to benefit from app start times (via
spring
) and reduced needfor full app restarts.
Step 1: Remove any previous configuration
Things to note down before starting:
use
bundle info factory_bot
orbundle info factory_bot_rails
most of the time those come in the form of requires in your
spec_helper
, e.g.require 'spree/testing_support/factories'
anything like
require 'spree/testing_support/factories/user_factory'
, checkboth your spec helper files and your factories
A laundry list of places that could include FactoryBot related code:
factory_bot
orfactory_bot_rails
from theGemfile
spec_helper.rb
,rails_helper.rb
, orspec/support
code related to FactoryBot, including requires comingconfig/application.rb
or inside initializers, e.g.config/initializers/factory_bot.rb
Step 2: Add back the updated configuration
1. Add the
factory_bot_rails
gemAdd
gem 'factory_bot_rails', '~> 4.8'
to yourGemfile
, we advise to use the same versionused by Solidus to ensure you don't get errors from differences in how FactoryBot builds/creates
associations, but if your app was based on a more recent version you might prefer to stick to
that one instead.
Gemfile
2. Configure paths in
config/application.rb
The initializer should look like this:
config/application.rb
3. Setup the RSpec helpers
As advised by the FactoryBot readme:
spec/support/factory_bot.rb
🎉 That's all!
Beta Was this translation helpful? Give feedback.
All reactions