🎉 I'm releasing 12 products in 12 months! If you love product, checkout my new blog workingoutloud.dev

Back to home

Up and running with Factory Bot in Rails 5

    This post is a short getting-up-and-running style of post.

    It expects that you have Rails 5 setup and ready to roll.

    Why Factory Bot?

    From the world's most reliable resource Wikipedia:

    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.

    There is more info on the why on the Why Factories article.

    This is simply a quick start to get up and going to test model validation.

    Quick start

    rails new <project> -- api cd <project> gem install rspec factory_bot_rails

    Update Gemfile config

    In the Gemfile:

    group :development, :test do gem 'factory_bot_rails', '~>6.0' gem 'rspec-rails', '>= 3.9.0' end

    Run bundle install.

    Automatic factory definition loading

    From the docs:

    By default, factory_bot_rails will automatically load factories defined in the following locations, relative to the root of the Rails project:

    factories.rb test/factories.rb spec/factories.rb factories/*.rb test/factories/*.rb spec/factories/*.rb

    If you want to, you can set custom configuration in config/application.rb or the appropraite env config.

    config.factory_bot.definition_file_paths = ["custom/factories"]

    This will cause factory_bot_rails to automatically load factories in custom/factories.rb and custom/factories/*.rb.

    Config

    Add the following configuration to test/support/factory_bot.rb:

    # test/support/factory_bot.rb require "factory_bot_rails" RSpec.configure do |config| config.include FactoryBot::Syntax::Methods end

    Be sure to require that file in test/test_helper.rb:

    # test/test_helper.rb ENV["RAILS_ENV"] ||= "test" require_relative "../config/environment" require_relative "./support/factory_bot" require "rails/test_help" require "rspec/rails" class ActiveSupport::TestCase # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. fixtures :all # Add more helper methods to be used by all tests here... end

    Create a model

    From the guides, we are going to generate a new model.

    rails generate model Article title:string text:text # run the migration rails db:migrate

    If successful, the migration should return:

    == CreateArticles: migrating ================================================== -- create_table(:articles) -> 0.0019s == CreateArticles: migrated (0.0020s) =========================================

    Update Ruby

    Update app/models/article.rb to look like the following:

    class Article < ApplicationRecord validates :title, presence: true, length: {minimum: 5} validates :text, presence: true, length: {minimum: 5} end

    Add the following to the factories directory

    # test/factories/articles.rb FactoryBot.define do factory :article do title { "MyString" } text { "MyText" } end end

    Add an Rspec for the model

    # test/models/article_test.rb require "./test/test_helper" class ArticleTest < ActiveSupport::TestCase describe "article model" do before(:all) do @article1 = FactoryBot.create(:article) end it "is valid with valid attributes" do expect(@article1).to be_valid end it "is not valid without a title" do article2 = FactoryBot.build(:article, title: nil) expect(article2).to_not be_valid end it "is not valid without text" do article2 = FactoryBot.build(:article, text: nil) expect(article2).to_not be_valid end it "is not valid without a title of min length 5" do article2 = FactoryBot.build(:article, title: "Min") expect(article2).to_not be_valid end it "is not valid without text of min length 5" do article2 = FactoryBot.build(:article, text: "Min") expect(article2).to_not be_valid end end end

    Running the test

    rspec test/models/article_test.rb

    We should get something like the following out:

    ..... Finished in 0.04765 seconds (files took 0.90722 seconds to load) 5 examples, 0 failures Run options: --seed 18801 # Running: Finished in 0.001607s, 0.0000 runs/s, 0.0000 assertions/s. 0 runs, 0 assertions, 0 failures, 0 errors, 0 skips

    Resources and Further Reading

    1. thoughtbot/factory_bot_rails
    2. thoughtbot/factory_bot
    3. Why Factories?
    4. Creating an Article model in Rails
    5. Testing RSpec

    Image credit: Alex Knight

    Personal image

    Dennis O'Keeffe

    @dennisokeeffe92
    • Melbourne, Australia

    Hi, I am a professional Software Engineer. Formerly of Culture Amp, UsabilityHub, Present Company and NightGuru.
    I am currently working on Visibuild.

    1,200+ PEOPLE ALREADY JOINED ❤️️

    Get fresh posts + news direct to your inbox.

    No spam. We only send you relevant content.

    Up and running with Factory Bot in Rails 5

    Introduction

    Share this post