Factory Bot Cheat Sheet

From WikiOD

Here is the cheatsheat of Factory Bot and basic guide on how to use Factory Bot

Factories[edit | edit source]

{: .-three-column}

Introduction[edit | edit source]

{: .-intro}

Factory Bot is a helper for writing factories for Ruby tests. It was previously known as Factory Girl. For older versions, use FactoryGirl instead of FactoryBot.

Defining factories[edit | edit source]

FactoryBot.define do
  factory :user do
    first_name { 'John' }
    last_name  { 'Doe' }
    birthdate  { 21.years.ago }
    admin { false }

    sequence(:username) { |n| "user#{n}" }
  end
end

{: data-line=“2”}

See: Defining factories

Extra options[edit | edit source]

Custom class names[edit | edit source]

factory :user, class: 'User' do
  ···
end

Aliases[edit | edit source]

factory :user, aliases: [:author] do
  ···
end

Using[edit | edit source]

Build a model[edit | edit source]

FactoryBot.build(:user)

Other ways[edit | edit source]

build(:user)           # → model (not saved)
create(:user)          # → model (saved)
attributes_for(:user)  # → hash
build_stubbed(:user)   # stubbed out attributes

With options[edit | edit source]

build(:user, name: 'John')

Lists[edit | edit source]

create_list(:user, 3)
build_list(:user, 3)

Associations[edit | edit source]

Defining[edit | edit source]

factory :post do
  association :author, factory: :user
  association :author, factory: [:user, :admin]
end

{: data-line=“2,3”}

or[edit | edit source]

factory :post do
  author  # assumes there's a factory :author
end

After-create hooks[edit | edit source]

factory :post do
  after :create do |post|
    create :theme, post: post             # has_one
    create_list :comment, 3, post: post   # has_many
  end
end

{: data-line=“2”}

Other features[edit | edit source]

{: .-three-column}

Traits[edit | edit source]

factory :user do
  trait :admin do
    admin { true }
  end
end

{: data-line=“2,3,4”}

create :user, :admin

Traits allow you to group attributes together. See: Traits

Nested factories[edit | edit source]

factory :user do
  first_name { 'John' }

  factory :sample_user do
    first_name { FFaker::Name.first_name }
  end
end

{: data-line=“4,5,6”}

create :sample_user

See: Inheritance

Sub-factories[edit | edit source]

factory :user do
  ···
end
factory :sample_user, parent: :user do
  first_name { FFaker::Name.first_name }
end

{: data-line=“1”}

create :sample_user

Works the same as nested factories.

Options (transients)[edit | edit source]

factory :user do
  transient do
    upcased { true }
  end

  after :create do |user, options|
    user.name.upcase! if options.upcased
  end
end

{: data-line=“2,3,4”}

create(user, upcased: true)

Transient attributes will not get passed to the model, but will be available in after-create hooks. See: Transient attributes

Paths[edit | edit source]

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

Place your factories in these locations. {: .-setup}

See also[edit | edit source]

{: .-one-column}

Credit:rstacruz