Back to Repositories

Testing Factory Trait Inheritance and Modification in factory_bot

This test suite examines the behavior of modifying inherited factories with traits in FactoryBot, focusing on attribute overriding and factory modification. It verifies the correct handling of trait inheritance, attribute overrides, and factory modifications in a Ruby testing environment.

Test Coverage Overview

The test suite provides comprehensive coverage of FactoryBot’s trait inheritance and modification capabilities:

  • Verification of basic trait overrides for single attributes
  • Testing of complex trait combinations with multiple attributes
  • Validation of factory modifications after initial definition
  • Edge cases for attribute inheritance and overriding

Implementation Analysis

The testing approach utilizes RSpec’s describe/it blocks to structure the test cases systematically. The implementation leverages FactoryBot’s define/modify DSL to create and alter factory definitions, with specific focus on trait inheritance patterns and attribute overriding mechanisms.

  • Factory definition with nested traits and factories
  • Dynamic attribute value assignment
  • Factory modification using the modify block

Technical Details

Testing infrastructure includes:

  • RSpec as the testing framework
  • FactoryBot for test data generation
  • Model definition using define_model helper
  • Boolean, string, and integer attribute types
  • Factory trait definitions and inheritance

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Clear separation of concerns in test organization
  • Comprehensive validation of attribute values
  • Isolated test cases for specific functionality
  • Proper setup and context definition
  • Effective use of factory inheritance and traits

thoughtbot/factory_bot

spec/acceptance/modify_inherited_spec.rb

            
describe "modifying inherited factories with traits" do
  before do
    define_model("User", gender: :string, admin: :boolean, age: :integer)
    FactoryBot.define do
      factory :user do
        trait(:female) { gender { "Female" } }
        trait(:male) { gender { "Male" } }

        trait(:young_admin) do
          admin { true }
          age { 17 }
        end

        female
        young_admin

        factory :female_user do
          gender { "Female" }
          age { 25 }
        end

        factory :male_user do
          gender { "Male" }
        end
      end
    end
  end

  it "returns the correct value for overridden attributes from traits" do
    expect(FactoryBot.build(:male_user).gender).to eq "Male"
  end

  it "returns the correct value for overridden attributes from traits defining multiple attributes" do
    expect(FactoryBot.build(:female_user).gender).to eq "Female"
    expect(FactoryBot.build(:female_user).age).to eq 25
    expect(FactoryBot.build(:female_user).admin).to eq true
  end

  it "allows modification of attributes created via traits" do
    FactoryBot.modify do
      factory :male_user do
        age { 20 }
      end
    end

    expect(FactoryBot.build(:male_user).gender).to eq "Male"
    expect(FactoryBot.build(:male_user).age).to eq 20
    expect(FactoryBot.build(:male_user).admin).to eq true
  end
end