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:
FactoryBot.define dofactory :task dosequence(:title) { |n| "Task #{n}" }endend
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:
FactoryBot.define dosequence :email do |n|"user_#{n}@test.com"endfactory :user doname "Fred Flintstone"endend
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 ...