Linting Factories
factory_bot allows for linting known factories:
FactoryBot.lint
FactoryBot.lint
creates each factory and catches any exceptions raised during
the creation process. FactoryBot::InvalidFactoryError
is raised with a list
of factories (and corresponding exceptions) for factories which could not be
created.
Recommended usage of FactoryBot.lint
is to run this in a separate task before
your test suite is executed. Running it in a before(:suite)
will negatively
impact the performance of your tests when running single tests.
Example Rake task:
# lib/tasks/factory_bot.rake
namespace :factory_bot do
desc "Verify that all FactoryBot factories are valid"
task lint: :environment do
if Rails.env.test?
conn = ActiveRecord::Base.connection
conn.transaction do
FactoryBot.lint
raise ActiveRecord::Rollback
end
else
system("bundle exec rake factory_bot:lint RAILS_ENV='test'")
fail if $?.exitstatus.nonzero?
end
end
end
After calling FactoryBot.lint
, you'll likely want to clear out the database,
as records will most likely be created. The provided example above uses an SQL
transaction and rollback to leave the database clean.
You can lint factories selectively by passing only factories you want linted:
factories_to_lint = FactoryBot.factories.reject do |factory|
factory.name =~ /^old_/
end
FactoryBot.lint factories_to_lint
This would lint all factories that aren't prefixed with old_
.
Traits can also be linted. This option verifies that each and every trait of a
factory generates a valid object on its own. This is turned on by passing
traits: true
to the lint
method:
FactoryBot.lint traits: true
This can also be combined with other arguments:
FactoryBot.lint factories_to_lint, traits: true
You can also specify the strategy used for linting:
FactoryBot.lint strategy: :build
Verbose linting will include full backtraces for each error, which can be helpful for debugging:
FactoryBot.lint verbose: true