Girish Mahajan (Editor)

Factory Girl (Rails Testing)

Updated on
Edit
Like
Comment
Share on FacebookTweet on TwitterShare on LinkedInShare on Reddit

Factory Girl is a testing philosophy to test the Ruby on Rails applications which is perpendicular to Fixtures. Factory girl allows the user to quickly define prototypes for each of the models and ask for instances with properties that are important to the test at hand. Factory Girl replaces fixtures in tests. This way, the user does not have to keep the fixtures up-to-date as the data model changes. Fixtures can also tend to get unwieldy as more edge cases are added. On the other hand, Factory Girl generates data on the fly and adding and removing fields is much easier. The setup of Factory Girl is similar to Fixtures.

Contents

Description

Tests become much easier to maintain when you can request a model instance that is always current. Using Factory Girl, a model is never bound to a particular phase of the application’s development. They are dynamically loaded from the current state of application. When there are new customer attributes introduced in that latest merge, Factory Girl already sees them unlike the case with a directory of fixtures.
Factory Girl has simple definition syntax. It supports multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.

Installation

Factory Girl can be installed as a standard Ruby Gem install or installation can be included in the gem file and then bundle install can be run.

gem install factory_girl

Using Gemfile

# Add the following line to the Gemfile gem 'factory_girl' # Run bundle install from the shell

Fixtures

A good testing framework goes a long way in ensuring the software quality which is delivered to the customers. In testing, oftentimes data is critical but not always organized enough. Fixtures are a way of organizing test data; they reside in the fixtures folder in the project hierarchy of a rails application. Fixture is a fancy word for sample data which allows the user to populate the database with predefined data before the tests run.

Defining Factories

A factory is defined by a name and its set of attributes. The name of the factory is used to determine the class of the object. Class can also be specified explicitly.

It is a good practice to define factories providing basic attributes necessary for each class. Factories can also be inherited.

Linting a Factory

The process of executing a program that will analyze code for potential errors is called as linting. It is a good practice to run FactoryGirl.lint once before running the test suite. This will build all factories and call #valid? On the factories. If any factory returns False for the valid call, Factory girl returns FactoryGirl::InvalidFactoryError along with a list of factories that failed to load.

By default all factories can be linted as follows:

FactoryGirl.lint

To lint only selective factories, the following template can be used :

Less Boilerplate Code

The traditional fixture model allows the user to create a unit-test for a model and reuse it in numerous tests using references to the YAML files like :

But the issue with this method is that you need to create multiple copies of such YAML files for different values for the models.This issue does not arise in Factory Girl. Before asking for a model from Factory Girl, it needs to be told about how to build this model. This is specified in one or more factory files. These factory files can be saved in /test/factories.rb

Traits

Traits allow grouping of attributes which can be applied to any factory.

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

Alias

Factory Girl allows creating aliases for existing factories so that the factories can be reused.

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

Sequences

Factory Girl allows creating unique values for a test attribute in a given format.

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.

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

Parent factories can also be specified explicitly.

factory :user do name "Micheal" end factory :admin, parent: :user do admin_user true end

Callback

Factory Girl allows custom code to be injected at four different stages:

after(:build)
Code can be injected after the factory is built
before(:create)
Code can be injected before the factory is saved
after(:create)
Code can be injected after the factory is saved
after(:stub)
Code can be injected before the factory is stubbed

References

Factory Girl (Rails Testing) Wikipedia