position | chapter |
---|---|
7 |
Factory |
rom-factory
provides a simple API for creating and persisting ROM::Struct
's. If you already know FactoryBot you'll definitely understand the concept.
First of all you need to define a ROM Container for Factory. For example if you are using rspec
, you can add these lines to spec_helper.rb
. Also you need to require here all files with Factories.
Factory = ROM::Factory.configure do |config|
config.rom = my_rom_container
end
Dir[File.dirname(__FILE__) + '/support/factories/*.rb'].each { |file| require file }
# 'spec/support/factories/users.rb'
Factory.define(:user) do |f|
f.name 'John'
f.age 42
end
You can specify ROM relation if you want. It'll be pluralized factory name by default.
Factory.define(:user, relation: :people) do |f|
f.name 'John'
f.age 42
end
Struct User
will be found in MyApp::Entities
namespace
Factory.define(:user, struct_namespace: MyApp::Entities) do |f|
# ...
end
You can use sequences for uniq fields
Factory.define(:user) do |f|
f.name 'John'
f.sequence(:email) { |n| "john#{n}@example.com" }
end
Factory.define(:user) do |f|
f.name 'John'
f.timestamps
# same as
# f.created_at { Time.now }
# f.updated_at { Time.now }
end
- belongs_to
Factory.define(:group) do |f|
f.name 'Admins'
end
Factory.define(:user) do |f|
f.name 'John'
f.association(:group)
end
- has_many
Factory.define(:group) do |f|
f.name 'Admins'
f.association(:user, count: 2)
end
Factory.define(:user) do |f|
f.name 'John'
end
Factory.define(:user) do |f|
f.name 'John'
f.admin false
end
Factory.define(admin: :user) do |f|
f.admin true
end
# Factory.structs[:admin]
Factory.define(:user) do |f|
f.name 'John'
f.admin false
f.trait :with_age do |t|
t.age 42
end
end
# Factory.structs[:user, :with_age]
Build-in Faker objects
Factory.define(:user) do |f|
f.email { fake(:internet, :email) }
end
Passing the unique: true option will use Faker's unique feature
Factory.define(:user) do |f|
f.email { fake(:internet, :email, unique: true) }
end
Attributes can be based on the values of other attributes:
Factory.define(:user) do |f|
f.full_name { fake(:name) }
# Dependent attributes are inferred from the block parameter names:
f.login { |full_name| full_name.downcase.gsub(/\s+/, '_') }
# Works with sequences too:
f.sequence(:email) { |n, login| "#{login}-#{n}@example.com" }
end
# Create in-memory object
Factory.build(:user)
# Persist struct in database
Factory.create(:user)
# Override attributes
Factory.create(:user, age: 24)
# Build and Create via #[] accessors
Factory.structs[:user]
Factory[:user]