Back to Repositories

Testing Factory Definition Patterns in factory_bot

This test suite validates factory_bot’s custom class name functionality and Symbol#to_proc attribute definitions in factory definitions. It ensures proper object instantiation and attribute assignment behaviors in Ruby factory patterns.

Test Coverage Overview

The test suite covers two main aspects of factory_bot functionality:
  • Custom class name handling for factory definitions
  • Symbol#to_proc attribute value assignment
  • Override behavior for attribute values
  • Password confirmation matching scenarios

Implementation Analysis

The testing approach utilizes RSpec’s describe/it blocks to verify factory behavior. It employs dynamic model definition and factory configuration to test:
  • Factory instantiation with custom class mappings
  • Attribute value propagation using Symbol#to_proc
  • Value override scenarios in factory instantiation

Technical Details

Testing infrastructure includes:
  • RSpec as the testing framework
  • factory_bot for test data generation
  • Dynamic model definition helpers
  • Boolean and string attribute types
  • Custom factory configuration blocks

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Isolated test scenarios with clear setup
  • Comprehensive edge case coverage
  • DRY principle in attribute definitions
  • Clear separation of concerns between different factory behaviors
  • Explicit verification of object types and attributes

thoughtbot/factory_bot

spec/acceptance/definition_spec.rb

            
describe "an instance generated by a factory with a custom class name" do
  before do
    define_model("User", admin: :boolean)

    FactoryBot.define do
      factory :user

      factory :admin, class: User do
        admin { true }
      end
    end
  end

  subject { FactoryBot.create(:admin) }

  it { should be_kind_of(User) }
  it { should be_admin }
end

describe "attributes defined using Symbol#to_proc" do
  before do
    define_model("User", password: :string, password_confirmation: :string)

    FactoryBot.define do
      factory :user do
        password { "foo" }
        password_confirmation(&:password)
      end
    end
  end

  it "assigns values correctly" do
    user = FactoryBot.build(:user)

    expect(user.password).to eq "foo"
    expect(user.password_confirmation).to eq "foo"
  end

  it "assigns value with override correctly" do
    user = FactoryBot.build(:user, password: "bar")

    expect(user.password).to eq "bar"
    expect(user.password_confirmation).to eq "bar"
  end

  it "assigns overridden value correctly" do
    user = FactoryBot.build(:user, password_confirmation: "bar")

    expect(user.password).to eq "foo"
    expect(user.password_confirmation).to eq "bar"
  end
end