Back to Repositories

Testing Sequence Context Evaluation in Factory Bot

This test suite validates sequence context handling in Factory Bot, focusing on how sequences are evaluated within factory definitions. It ensures proper context management for sequence generation and method invocation within factory instances.

Test Coverage Overview

The test suite comprehensively covers sequence evaluation contexts in Factory Bot factories.

Key areas tested include:
  • Sprintf formatting in sequences
  • Public method invocation within sequences
  • Method calling without arguments
  • Direct attribute reference in sequences

Implementation Analysis

The testing approach utilizes RSpec to verify sequence behavior in different contexts. It employs dynamic class definition and factory creation patterns to test various sequence implementations.

Technical implementation details:
  • Dynamic class definition using define_class
  • Factory definition with sequence blocks
  • Method context preservation testing
  • String interpolation validation

Technical Details

Testing tools and configuration:
  • RSpec testing framework
  • Factory Bot gem for factory definitions
  • Dynamic class creation for test isolation
  • Sequence block syntax for attribute generation

Best Practices Demonstrated

The test suite exemplifies several testing best practices for factory sequence implementation.

Notable practices include:
  • Isolated test cases for each sequence scenario
  • Clear test descriptions and expectations
  • Proper setup and teardown using before blocks
  • Comprehensive coverage of edge cases

thoughtbot/factory_bot

spec/acceptance/sequence_context_spec.rb

            
describe "sequences are evaluated in the correct context" do
  before do
    define_class("User") do
      attr_accessor :id

      def awesome
        "aw yeah"
      end
    end
  end

  it "builds a sequence calling sprintf correctly" do
    FactoryBot.define do
      factory :sequence_with_sprintf, class: User do
        sequence(:id) { |n| sprintf("foo%d", n) }
      end
    end

    expect(FactoryBot.build(:sequence_with_sprintf).id).to eq "foo1"
  end

  it "invokes the correct method on the instance" do
    FactoryBot.define do
      factory :sequence_with_public_method, class: User do
        sequence(:id) { public_method(:awesome).call }
      end
    end

    expect(FactoryBot.build(:sequence_with_public_method).id).to eq "aw yeah"
  end

  it "invokes a method with no arguments on the instance" do
    FactoryBot.define do
      factory :sequence_with_frozen, class: User do
        sequence(:id) { frozen? }
      end
    end

    expect(FactoryBot.build(:sequence_with_frozen).id).to be false
  end

  it "allows direct reference of a method in a sequence" do
    FactoryBot.define do
      factory :sequence_referencing_attribute_directly, class: User do
        sequence(:id) { |n| "#{awesome}#{n}" }
      end
    end
    expect(FactoryBot.build(:sequence_referencing_attribute_directly).id).to eq "aw yeah1"
  end
end