Always include the syntax helpers in your tests. This makes build
and create
available in your test cases.
# rails_helper.rb
config.include FactoryBot::Syntax::Methods
Prefer build
over create
, if you can get away with it. This can lead to faster tests. Avoid build_stubbed
.
Never hard-code emails and similar fields that must be unique. Use sequence
when possible.
factory :user do
sequence(:email) { |i| "user-#{i}@email.com" }
...
end
Place reusable sequences in a separate file.
# spec/factories/factory_sequences.rb
FactoryBot.define do
sequence(:uid) { |i| SecureRandom.uuid }
sequence(:email) { |i| "user-#{i}@email.com" }
end
factory :admin do
uid
email
end
factory :client do
uid
email
end
Traits can be used to remove duplication, but use them sparingly.
Make sure that factories are always up to date.
Always provide the simplest defaults for your factories. Prefer to only add fields that are validated such that records built through the factory will pass validation. Other fields would only serve to make for confusing future tests and make it difficult to test default behavior.
class Profile < ActiveRecord::Base
validates :name, presence: true
validates :gender, inclusion: %w(male female)
end
factory :profile do
name "Jack Sparrow"
gender "male"
occupation "Pirate" # <- Don't
bio "Jack is a pirate lord of the seven seas." # <- Don't
end
Test your factories. This will make it easy to spot any factories that may be out of date.
EXCLUDED = [:factories, :to, :exclude, :if, :any]
FactoryBot.factories.map(&:name).each do |factory_name|
next if EXCLUDED.include?(factory_name)
it "the #{factory_name} factory is valid" do
expect(build factory_name).to be_valid
end
end