Factory Bot (Rails Testing)

Factory Bot, originally known as Factory Girl,[1] is a software library for the Ruby programming language that provides factory methods to create test fixtures for automated software testing. The fixture objects can be created on the fly; they may be plain Ruby objects with a predefined state, ORM objects with existing database records or mock objects.

Factory Bot is often used in testing Ruby on Rails applications; where it replaces Rails' built-in fixture mechanism. Rails' default setup uses a pre-populated database as test fixtures, which are global for the complete test suite. Factory Bot, on the other hand, allows developers to define a different setup for each test and thus helps to avoid dependencies within the test suite.[2][3]

Factories

Defining Factories

A factory is defined by a name and its set of attributes. The class of the test object is either determined through the name of the factory or set explicitly.[4]

<syntaxhighlight lang="ruby"> FactoryBot.define do

 # Determine class automatically
 factory :user do
   name { "Captain Minion" }
   superhero { false }
 end
 
 # Specify class explicitly
 factory :superhero, class: User do
   name { "Tony Stark" }
   superhero { true }
 end

end </syntaxhighlight>

Features

Traits

Traits allow grouping of attributes which can be applied to any factory.[4][5]

<syntaxhighlight lang="ruby"> factory :status do

 title { "Seeking for Full Time jobs" }

 trait :international do
   international { true }
 end

 trait :resident do
   international { false }
 end

 trait :comp_sci do
   comp_sci { true }
 end

 trait :electrical do
   comp_sci { false }
 end
	
 factory :comp_sci_international_student,  traits: [:international, :comp_sci]
 factory :electrical_resident_student,  traits: [:resident, :electrical]

end </syntaxhighlight>

Alias

Factory Bot allows creating aliases for existing factories so that the factories can be reused.[4]

<syntaxhighlight lang="ruby"> factory :user, aliases: [:student, :teacher] do

 first_name { "John" }

end

factory :notice do

 teacher
 # Alias used teacher for user
 title { "Office Hours" }
end

factory :notification do

 student
 #Alias used student for user 
 title { "Lecture timings" }

end </syntaxhighlight>

Sequences

Factory Bot allows creating unique values for a test attribute in a given format.[4]

<syntaxhighlight lang="ruby"> FactoryBot.define do

 factory :title do
   sequence(:name) {|n| "Title #{n}" }
   # Title 1, Title 2 and so on...
 end

end </syntaxhighlight>

Inheritance

Factories can be inherited while creating a factory for a class. This allows the user to reuse common attributes from parent factories and avoid writing duplicate code for duplicate attributes. Factories can be written in a nested fashion to leverage inheritance.

<syntaxhighlight lang="ruby"> factory :user do

 name { "Micheal" }
 factory :admin do
   admin_rights true
 end

end

admin_user = create(:admin) admin_user.name # Micheal admin_user.admin_rights # true </syntaxhighlight>

Parent factories can also be specified explicitly. <syntaxhighlight lang="ruby"> factory :user do

 name { "Micheal" }

end

factory :admin, parent: :user do

 admin_user { true }

end </syntaxhighlight>

Callback

Factory Bot allows custom code to be injected at four different stages:[4]

<syntaxhighlight lang="text" class="" style="" inline="1">after(
build)</syntaxhighlight>: Code can be injected after the factory is built
<syntaxhighlight lang="text" class="" style="" inline="1">before(
create)</syntaxhighlight>: Code can be injected before the factory is saved
<syntaxhighlight lang="text" class="" style="" inline="1">after(
create)</syntaxhighlight>: Code can be injected after the factory is saved
<syntaxhighlight lang="text" class="" style="" inline="1">after(
stub)</syntaxhighlight>: Code can be injected before the factory is stubbed

See also

Other Test libraries for Ruby

  • NullDB: a way to speed up testing by avoiding database use.
  • Fixture Builder: a tool that compiles Ruby factories into fixtures before a test run.
  • Shoulda: an extension to test/unit with additional helpers, macros, and assertions.
  • Rspec: a behavior-driven development framework
  • Capybara: Acceptance test framework for web applications.

References

  1. ^ "Project Naming History". github.com/thoughtbot/factory_bot.
  2. ^ "Waiting For a FactoryGirl". Thoughtbot Blog.
  3. ^ "Rails Testing". hiringthing.com.
  4. ^ 4.0 4.1 4.2 4.3 4.4 "Getting Started". rubydoc.info/gems/factory_bot.
  5. ^ "Traits". Thoughtbot Blog.