Skip to content
Collection of helpers for dealing with fixtures in RSpec
Branch: master
Clone or download
Latest commit f757a85 Jun 9, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib Support serialization of Ruby objects via ERB Jun 9, 2019
spec Support serialization of Ruby objects via ERB Jun 9, 2019
.gitignore Add RubyMine .idea/ to ignored paths Jun 9, 2019
.rspec Initial commit Jan 30, 2019
.rubocop.yml Bump v0.0.2 Apr 27, 2019
.travis.yml Bump v0.0.2 Apr 27, 2019 Bump v0.0.6 Jun 9, 2019
Gemfile Initial commit Jan 30, 2019
LICENSE.txt Initial commit Jan 30, 2019 Update Jun 9, 2019
Rakefile Initial commit Jan 30, 2019
fixturama.gemspec Bump v0.0.6 Jun 9, 2019


Collection of helpers for dealing with fixtures in RSpec

Read the post about the library on

Sponsored by Evil Martians

Gem Version Build Status


gem "fixturama"


On Rails add offsets to id sequences of database tables.

# spec/rails_helper.rb
RSpec.configure do |config|
  config.before(:suite) { Fixturama.start_ids_from 1_000_000 }

Now when you hardcode ids in fixtures (under 1_000_000), they won't conflict with authomatically created ones.


# spec/spec_helper.rb
require "fixturama/rspec"

The gem defines 3 helpers (support ERB bindings):

  • load_fixture(path, **opts) to load data from a fixture, and deserialize YAML and JSON
  • seed_fixture(path_to_yaml, **opts) to prepare database using the FactoryBot
  • stub_fixture(path_to_yaml, **opts) to stub some classes


# spec/models/user/_spec.rb
RSpec.describe "GraphQL mutation 'deleteProfile'" do
  subject { Schema.execute(mutation).to_h }

  before do
    seed_fixture("#{__dir__}/database.yml", profile_id: 42)
    stub_fixture("#{__dir__}/stubs.yml",    profile_id: 42)

  let(:mutation) { load_fixture "#{__dir__}/mutation.graphql", profile_id: 42 }
  let(:result)   { load_fixture "#{__dir__}/result.yaml" }

  it { eq result }

  it "deletes the profile" do
    expect { subject }.to change { Profile.find_by(id: 42) }.to nil

  it "sends a notification" do
      .to receive_message_chain(:create)
      .with("profileDeleted", 42)


Notice, that since the v0.0.6 the gem also supports binding any ruby object, not only strings, booleans and numbers:

# ./data.yml
account: <%= user %>
# Bind activerecord model
subject { load_fixture "#{__dir__}/data.yml", user: user }

let(:user) { FactoryBot.create :user }

# The same object will be returned
it { eq account: user }

The object must be named in the options you send to the load_fixture, stub_fixture, or seed_fixture helpers.

This feature can also be useful to produce a "partially defined" fixtures with RSpec argument matchers:

subject { load_fixture "#{__dir__}/data.yml", user: kind_of(ActiveRecord::Base) }


The seed (seed_fixture) file should be a YAML/JSON with opinionated parameters, namely:

  • type for the name of the FactoryBot factory
  • traits for the factory traits
  • params for parameters of the factory
# ./database.yml
# This is the same as
# `create_list :profile, 1, :active, id: profile_id`
- type: profile
    - active
    id: <%= profile_id %>

Use the count: 2 key to create more objects at once.


Another opinionated format we use for stubs (stub_fixture). The gem supports stubbing both message chains and constants.

For message chains:

  • class for stubbed class
  • chain for messages chain
  • arguments (optional) for specific arguments
  • actions for an array of actions for consecutive invocations of the chain

For constants:

  • const for stubbed constant
  • value for a value of the constant

Every action either return some value, or raise some exception

# ./stubs.yml
# The first invocation acts like
# allow(Notifier)
#   .to receive_message_chain(:create)
#   .with(:profileDeleted, 42)
#   .and_return true
# then it will act like
# allow(Notifier)
#   .to receive_message_chain(:create)
#   .with(:profileDeleted, 42)
#   .and_raise ActiveRecord::RecordNotFound
- class: Notifier
    - create
    - :profileDeleted
    - <%= profile_id %>
    - return: true
    - raise: ActiveRecord::RecordNotFound

  value: 10
mutation {
    input: {
      id: "<%= profile_id %>"
  ) {
    errors {
# ./result.yaml
    success: true
    errors: []

With these helpers all the concrete settings can be extracted to fixtures.

I find it especially helpful when I need to check different edge cases. Instead of polluting a specification with various parameters, I create the sub-folder with "input" and "output" fixtures for every case.

Looking at the spec I can easily figure out the "structure" of expectation, while looking at fixtures I can check the concrete corner cases.


The gem is available as open source under the terms of the MIT License.

You can’t perform that action at this time.