Back to Repositories

Testing Sequence Attribute Generation in factory_bot

This test suite examines the sequence attribute functionality in FactoryBot, focusing on how sequential values are generated and assigned. It validates the core sequence generation mechanism used for creating unique test data values with predictable patterns.

Test Coverage Overview

The test suite provides comprehensive coverage of FactoryBot’s sequence attribute functionality.

Key areas tested include:
  • Sequence name assignment and retrieval
  • Sequential value generation with custom starting points
  • Proper execution of sequence blocks
  • Integration with FactoryBot’s internal sequence registry

Implementation Analysis

The testing approach uses RSpec’s describe/let pattern to establish a controlled test environment for sequence operations. The implementation leverages RSpec’s subject/its syntax for property verification and explicit expectation blocks for behavior testing.

Technical patterns include:
  • Subject-based testing with explicit attribute definition
  • Sequence registration in setup phase
  • Closure-based value generation verification

Technical Details

Testing infrastructure includes:
  • RSpec as the testing framework
  • FactoryBot’s internal sequence registry
  • Custom sequence block definitions
  • Before hooks for test state setup

Best Practices Demonstrated

The test suite exemplifies several testing best practices in Ruby unit testing.

Notable practices include:
  • Isolated test setup using let blocks
  • Clear separation of setup and expectations
  • Focused test cases with single assertions
  • Proper use of RSpec’s declarative syntax

thoughtbot/factory_bot

spec/factory_bot/attribute/sequence_spec.rb

            
describe FactoryBot::Attribute::Sequence do
  let(:sequence_name) { :name }
  let(:name) { :first_name }
  let(:sequence) { FactoryBot::Sequence.new(sequence_name, 5) { |n| "Name #{n}" } }

  subject { FactoryBot::Attribute::Sequence.new(name, sequence_name, false) }
  before { FactoryBot::Internal.register_sequence(sequence) }

  its(:name) { should eq name }

  it "assigns the next value in the sequence" do
    expect(subject.to_proc.call).to eq "Name 5"
  end
end