Here's something that works well for me. I want to create deeply nested structures without specifying individual factories for each nesting. My usecase is stubbing external apis with webmock. Fixtures don't cut it for me since I need to stub in a variety of different data.
Define the following base factory and support code:
FactoryBot.define do
factory :json, class: Hash do
# Don't try to persist the object
skip_create
# Grab only what is defined in the json block
initialize_with { attributes[:json].to_json }
end
end
I can then define the actual factory like this:
FactoryBot.define do
factory :json_response, parent: :json do
# You can define any attributes you want here
# to use as parameters in the json block
ids { [] }
# The result of this block is what FactoryBot will return
json do
ids.map do |id|
{
score: 90,
data: {
id: id,
},
}
end
end
end
end
Finally you can use it like this:
FactoryBot.build(:json_response, ids: [1,2])
=> "[{\"score\":90,\"data\":{\"id\":1}},{\"score\":90,\"data\":{\"id\":2}}]"