philiprehberger-test_factory
Lightweight test data factory DSL with sequences and traits
Requirements
- Ruby >= 3.1
Installation
Add to your Gemfile:
gem "philiprehberger-test_factory"Or install directly:
gem install philiprehberger-test_factoryUsage
require "philiprehberger/test_factory"
# Define a factory
Philiprehberger::TestFactory.define(:user) do
{ name: "Alice", email: "alice@example.com", role: "user" }
end
# Build a single object
user = Philiprehberger::TestFactory.build(:user)
# => { name: "Alice", email: "alice@example.com", role: "user" }
# Build with overrides
admin = Philiprehberger::TestFactory.build(:user, role: "admin")
# => { name: "Alice", email: "alice@example.com", role: "admin" }Traits
Philiprehberger::TestFactory.trait(:user, :admin) { { role: "admin" } }
Philiprehberger::TestFactory.trait(:user, :inactive) { { active: false } }
admin = Philiprehberger::TestFactory.build(:user, traits: [:admin])
# => { name: "Alice", email: "alice@example.com", role: "admin" }Sequences
Philiprehberger::TestFactory.sequence(:email) { |n| "user_#{n}@example.com" }
# Access via the registry
email = Philiprehberger::TestFactory.send(:registry).next_in_sequence(:email)
# => "user_1@example.com"Build Lists
users = Philiprehberger::TestFactory.build_list(:user, 5)
# => Array of 5 user hashesCallbacks
Philiprehberger::TestFactory.define(:user) do |f|
f.after_build { |obj| obj[:created_at] = Time.now }
{ name: "Alice", email: "alice@example.com" }
endTransient Attributes
Philiprehberger::TestFactory.define(:user) do |f|
f.transient { admin false }
f.after_build { |obj, transients| obj[:role] = "admin" if transients[:admin] }
{ name: "Alice", role: "user" }
end
user = Philiprehberger::TestFactory.build(:user, admin: true)
# => { name: "Alice", role: "admin" }Associations
Philiprehberger::TestFactory.define(:user) { { name: "Alice" } }
Philiprehberger::TestFactory.define(:post) do |f|
f.association :author, factory: :user
{ title: "Hello World" }
end
post = Philiprehberger::TestFactory.build(:post)
# => { title: "Hello World", author: { name: "Alice" } }Reset
Philiprehberger::TestFactory.reset!API
| Method | Description |
|---|---|
TestFactory.define(name, &block) |
Register a factory; block returns a hash of defaults |
TestFactory.trait(factory_name, trait_name, &block) |
Register a trait override for a factory |
TestFactory.sequence(name, &block) |
Register a thread-safe auto-incrementing sequence |
TestFactory.build(name, traits:, **overrides) |
Build a single data hash |
TestFactory.build_list(name, count, traits:, **overrides) |
Build N data hashes |
TestFactory.reset! |
Clear all definitions, traits, and sequences |
DefinitionProxy#after_build(&block) |
Register a callback that runs after building |
DefinitionProxy#transient(&block) |
Declare transient attributes excluded from the result |
DefinitionProxy#association(name, factory:) |
Declare an association to another factory |
Development
bundle install
bundle exec rspec
bundle exec rubocopSupport
If you find this project useful: