...

/

Managing Duplication in Factories

Managing Duplication in Factories

Learn about factory_bot's features, traits, resources, and validations.

Once we have more than a couple of factories in our application, we want to make sure we can manage complexity and duplication. The factory_bot has several features to allow us to do just that.

Sequences

A common problem is the creation of multiple objects that require unique values. This most often happens with unique user attributes such as a login or email address. To easily create unique attributes, factory_bot allows us to define an attribute as part of a values sequence. The short version of the syntax looks like this:

Press + to interact
FactoryBot.define do
factory :task do
sequence(:title) { |n| "Task #{n}" }
end
end

Calling sequence inside a factory takes one argument (which is the attribute whose values are being sequenced) and a block. When the factory is invoked, the block is called with a new sequential value, and the block’s return value is set to be the value of the attribute. By default, the start value is 1, but a second argument to sequence can specify an arbitrary value. Usually, a number can be any object that responds to next.

When a sequence is defined inside a factory, it can be used in only that one place. However, sequences can also be defined outside of factories and reused:

Press + to interact
FactoryBot.define do
sequence :email do |n|
"user_#{n}@test.com"
end
factory :user do
name "Fred Flintstone"
email
end
end

The use of email inside the factory is a shortcut that assumes the sequence and the attribute have the same name. If so, the sequence is triggered, and the next value becomes the value of the attributes. If the sequence and the attribute have different names, then we need to invoke the sequence explicitly by calling generate inside an ...