What a classic Rails fixture is, and why this app has none

Free preview 3 min to read

Rails' doc comments, quoted

active_record/fixtures.rb, installed with this app's Rails 8.1.3.1, opens with a definition: "Fixtures are a way of organizing data that you want to test against; in short, sample data." They're plain YAML, one file per model, in test/fixtures/, Minitest's convention:

rubyonrails:
  id: 1
  name: Ruby on Rails
  url: http://www.rubyonrails.org

google:
  id: 2
  name: Google
  url: http://www.google.com

"The testing environment will automatically load all the fixtures into the database before each test," the comment continues. "To ensure consistent data, the environment deletes the fixtures before running the load." Every test starts from the same two rows, rubyonrails and google. Rails hands each one back through a method named after the file: web_sites(:rubyonrails).name, from the same doc comment.

This app has none

find spec/fixtures -type f
# => spec/fixtures/files/test_image.png

That one file is an image for testing file attachments, not a YAML data fixture in the sense the doc comment describes. No web_sites.yml-style file exists anywhere in this app, and there's no test/ directory either. This app committed to RSpec in spec/, with no Minitest and no classic fixtures. Both facts were checked on disk.

An ordering trap the doc comment warns about

The same source says: "Fixtures by default are unordered... You will need ordered fixtures when you have foreign key constraints on keys in the same table". Its fix is the YAML !omap type, which guarantees a parent row loads before the child row that references it. A YAML fixture file has no notion of "this row needs that row to exist first" beyond a raw id: value the author picks and keeps in sync by hand. The doc comment's recommended fix is markup, not code.

Why this matters before the next six lessons

This app's choice is factories: factory_bot_rails is in the Gemfile, and spec/factories/ holds 18 files with 21 factory :name declarations across the catalog, identity, enrollment, execution, partners and community namespaces. A few files define more than one factory, quizzes.rb and lesson_notes.rb among them. Factories aren't the only way to write test data. They're a deliberate choice against a well-documented alternative, the one this lesson just quoted from Rails' source. The next lessons show what that choice looks like in this app's code: the factory :name do ... end DSL, traits, the create/build/build_stubbed split, and associations built on the fly instead of hand-picked ids.

What this course covers

Seven lessons, checked against this app's spec/factories/ files and FactoryBot's installed source. This lesson covers what a YAML fixture is, and that this app has none. Lesson 2 covers the factory DSL: attributes and sequence. Lesson 3 covers traits, including a surprising finding about where many of this app's traits come from. Lesson 4 covers create, build, build_stubbed and attributes_for, with how often this app's suite uses each. Lesson 5 covers associations, and what gets saved when one factory references another. Lesson 6 weighs the tradeoff and why factories won here. Lesson 7 ends with a challenge: a small object builder with sequences, in plain Ruby.

Lesson 1 of 7 · free

Keep going with lesson 2

The factory DSL: attributes and sequence, checked against this app's files

Reads the user factory to explain attribute blocks, sequence counters for unique values, and call-site overrides.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...