Back to Repositories

Testing Nested Attributes Assignment Implementation in factory_bot

This test suite examines FactoryBot’s handling of nested attributes in ActiveRecord associations, specifically focusing on the Post-Comment relationship. It validates the proper creation and assignment of nested comment attributes when creating Post objects, demonstrating FactoryBot’s integration with Rails’ accepts_nested_attributes_for functionality.

Test Coverage Overview

The test suite covers the essential aspects of nested attribute assignment in FactoryBot:
  • Default nested attributes creation with multiple comments
  • Override capability for nested attributes during factory creation
  • Validation of comment count in both default and override scenarios
  • Integration with ActiveRecord association mechanisms

Implementation Analysis

The testing approach utilizes RSpec’s describe/it blocks to structure the test cases. It employs FactoryBot’s define_model helper for dynamic model creation, establishing a Post-Comment relationship with nested attributes support. The implementation showcases sequence usage for unique comment bodies and attributes_for helper for building nested attributes.

Technical Details

Key technical components include:
  • RSpec testing framework
  • FactoryBot’s define_model and attributes_for helpers
  • ActiveRecord associations (has_many, belongs_to)
  • accepts_nested_attributes_for configuration
  • Dynamic model definition with string and text column types

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Clear test organization with before block setup
  • Isolated test cases for default and override scenarios
  • Proper use of factory sequences for unique data
  • Efficient model relationship testing
  • Clean and maintainable factory definitions

thoughtbot/factory_bot

spec/acceptance/nested_attributes_spec.rb

            
describe "association assignment from nested attributes" do
  before do
    define_model("Post", title: :string) do
      has_many :comments
      accepts_nested_attributes_for :comments
    end

    define_model("Comment", post_id: :integer, body: :text) do
      belongs_to :post
    end

    FactoryBot.define do
      factory :post do
        comments_attributes { [FactoryBot.attributes_for(:comment), FactoryBot.attributes_for(:comment)] }
      end

      factory :comment do
        sequence(:body) { |n| "Body #{n}" }
      end
    end
  end

  it "assigns the correct amount of comments" do
    expect(FactoryBot.create(:post).comments.count).to eq 2
  end

  it "assigns the correct amount of comments when overridden" do
    post = FactoryBot.create(:post, comments_attributes: [FactoryBot.attributes_for(:comment)])

    expect(post.comments.count).to eq 1
  end
end