thoughtbot / thoughtbot/factory_bot
Expose defined factories
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 8.2k
- Forks
- 2.6k
- PR merge metrics
- No merged PRs in 30d
Description
Problem this feature will solve
I often find myself creating multiple factories for a given model, for various reasons — e.g.:
- fields with semantic constraints that can't easily be captured in factory logic
- references to other forms of test data such as image files
- working with copies of production data that surfaced particular issues
— and then writing multiple specs that all reference all of those factories, or some defined subset of them.
FactoryBot does not provide any documented way of easily doing this without unnecessary repetition; there's no out-of-the-box way to say, for instance "create all defined instances of model Qux", and even if there was, that wouldn't handle the subset case.
Desired solution
- Making
FactoryBot#factories,FactoryBot::RegistryandFactoryBot::Factory(at least
some subset of their methods) stable public APIs. This would be the most flexible solution
and most likely to address other use cases than mine. - Alternatively, add specific DSL methods, e.g. a
create_eachto create records from each
factory nested in a given root factory. This could work, esp. if it accepted a predicate
argument of some kind to handle subsets, but seems unnecessarily specific, and would
presumably require correspondingbuild_each,attributes_for_each, etc.
Alternatives considered
-
Current workaround: use the internal APIs anyway, and be prepared for them to break:
all_quxes = FactoryBot.factories .select { |f| f.build_class == Qux } .map { |n| create(:n) } my_quxes = FactoryBot.factories .select { |f| f.build_class == Qux && f.names.any? { |n| n.start_with?('my') } } .map { |n| create(:n) } -
When working with multiple records, create only generic data using the existing list
strategies.- Pros:
- Well documented, works out of the box, no new features
- Cons:
- can be hard to make generic data meet semantic constraints
- generic data is often less human-readable when diagnosing test failures
- by its nature, generic data can't easily capture specific situations
- Pros:
-
Go back to fixtures
- Pros:
- fixture definitions are in YAML, so we could write tooling to parse that and
instantiate them programmatically based on whatever criteria we wanted
- fixture definitions are in YAML, so we could write tooling to parse that and
- Cons:
- all the reasons we switched from fixtures to FactoryBot in the first place
- Pros:
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the current FactoryBot.factories, FactoryBot::Registry, and FactoryBot::Factory interfaces referenced in the issue, along with the existing list strategies. Compare stabilizing those APIs with adding create_each, build_each, and attributes_for_each, including subset selection; done requires an agreed public approach rather than relying on internal APIs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100