Factory Bot Integration
FakeDataDSL integrates seamlessly with Factory Bot to provide powerful test data generation with the simplicity of Factory Bot's DSL.
Quick Start
1. Define a Factory
# spec/factories.rb or spec/support/fake_data_factories.rb
require 'fake_data_dsl'
FakeDataDSL.define_factory(:user, schema: "User") do
trait(:admin) do
role { "admin" }
end
trait(:inactive) do
active { false }
end
trait(:with_address) do
address { FakeDataDSL.generate("Address") }
end
end
2. Use in Tests
# spec/models/user_spec.rb
RSpec.describe User do
it "creates a valid user" do
user = create(:user)
expect(user).to be_valid
end
it "creates an admin user" do
admin = create(:user, :admin)
expect(admin.role).to eq("admin")
end
it "accepts field overrides" do
user = create(:user, name: "Custom Name", email: "custom@example.com")
expect(user.name).to eq("Custom Name")
end
end
RSpec Helpers
Setup
# spec/spec_helper.rb
require 'fake_data_dsl'
require 'fake_data_dsl/factory_bot_integration'
RSpec.configure do |config|
config.include FakeDataDSL::FactoryBotIntegration::RSpec
end
Available Helpers
# Build data without creating records
user_data = fake_data_build(:user)
user_data = build_fake_data(:user) # Alias
# With traits
admin_data = fake_data_build(:user, :admin)
# With overrides
custom_data = fake_data_build(:user, :admin, name: "Jane Doe")
Defining Factories
Basic Factory
FakeDataDSL.define_factory(:user, schema: "User")
Factory with Traits
FakeDataDSL.define_factory(:user, schema: "User") do
trait(:admin) do
role { "admin" }
{ ["read", "write", "delete"] }
end
trait(:guest) do
role { "guest" }
{ ["read"] }
end
trait(:verified) do
email_verified { true }
phone_verified { true }
end
end
Combining Traits
# Traits can be combined
create(:user, :admin, :verified)
create(:user, :guest, name: "Anonymous")
Schema Requirements
Your DSL schemas should be loaded before defining factories:
# Load schemas first
FakeDataDSL.load_schemas("schemas/")
# Then define factories
FakeDataDSL.define_factory(:user, schema: "User")
FakeDataDSL.define_factory(:order, schema: "Order")
Example Schema
# schemas/user.dsl
User:
id: uuid
name: name
email: email
role: enum(user, admin, moderator)
active: boolean(true:90%)
created_at: timestamp
Advanced Usage
Custom Factory Logic
FakeDataDSL.define_factory(:user, schema: "User") do
trait(:with_orders) do
orders {
3.times.map { FakeDataDSL::FactoryBotIntegration.build(:order) }
}
end
end
Sequence Support
FakeDataDSL.define_factory(:user, schema: "User") do
trait(:numbered) do
# Use schema's built-in sequence type
# or override with custom sequence
id { |n| "user_#{n}" }
end
end
Dependent Attributes
FakeDataDSL.define_factory(:user, schema: "User") do
trait(:consistent_name) do
first_name { "John" }
last_name { "Doe" }
email { "john.doe@example.com" }
end
end
Integration with Factory Bot (Optional)
If Factory Bot is already installed, factories are automatically registered:
# This just works if Factory Bot is available
FactoryBot.create(:user)
FactoryBot.create(:user, :admin)
FactoryBot.build_list(:user, 10)
Best Practices
1. Organize Factories by Domain
# spec/support/factories/users.rb
FakeDataDSL.define_factory(:user, schema: "User") { ... }
FakeDataDSL.define_factory(:admin_user, schema: "AdminUser") { ... }
# spec/support/factories/orders.rb
FakeDataDSL.define_factory(:order, schema: "Order") { ... }
FakeDataDSL.define_factory(:order_item, schema: "OrderItem") { ... }
2. Use Traits for Common Scenarios
FakeDataDSL.define_factory(:user, schema: "User") do
# State traits
trait(:active) { active { true } }
trait(:inactive) { active { false } }
# Role traits
trait(:admin) { role { "admin" } }
trait(:guest) { role { "guest" } }
# Feature traits
trait(:with_2fa) { two_factor_enabled { true } }
trait(:premium) { subscription_tier { "premium" } }
end
3. Keep Factories DRY
# Base user factory
FakeDataDSL.define_factory(:user, schema: "User")
# Specialized factories inherit behavior
FakeDataDSL.define_factory(:admin, schema: "AdminUser") do
trait(:super_admin) { { ["all"] } }
end
Troubleshooting
Factory Not Found
# Error: Unknown factory: :user
# Solution: Ensure factory is defined before use
FakeDataDSL.define_factory(:user, schema: "User")
Schema Not Found
# Error: Unknown schema: User
# Solution: Load schemas before defining factories
FakeDataDSL.load_schemas("schemas/")
FakeDataDSL.define_factory(:user, schema: "User")
Trait Overrides Not Working
# Traits should return hashes or use block syntax
trait(:admin) do
role { "admin" } # Correct: block syntax
end
# Not: role: "admin" # This won't work as expected