Search code examples
ruby-on-rails-4rspec3fabrication-gem

Fabricators not loading


I get an empty array while trying to use fabricators in my specs. My guess is that the fabricator file has not loaded. If I load the fabricator file after RSpec's initialization then a Fabrication::DuplicateFabricatorError is raised. Here's my setup:

  • rails 4.1.4
  • rspec-core 3.1.5
  • rspec-rails 3.1.0
  • fabrication 2.11.3

.

# config/application.rb
config.generators do |g|
  g.test_framework      :rspec, fixture: true
  g.fixture_replacement :fabrication, dir: "spec/fabricators"
end

# spec/rails_helper.rb
config.fixture_path = "#{::Rails.root}/spec/fabricators"
config.use_transactional_fixtures = true

Here's the code that should be working but isn't:

# app/models/user.rb
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

# spec/fabricators/user_fabricator.rb
Fabricator(:user) do
  email                 { Faker::Internet.email }
  password              "password"
  password_confirmation "password"
end

# spec/models/user_spec.rb
require 'rails_helper'

describe User do
  before :each do
    @user = Fabricator(:user)
    #=> []
  end

  it "has an email" do
    expect(@user.email).to be_a(String)
    expect(@user.email.length).to be > 0
  end
end

After getting an empty array returned for my fabricator, I get this error when running specs: undefined method 'email' for []:Array. I expect to get a passing spec.


Solution

  • You have two issues here as far as I can see. The first is that you do not need this line in your rails_helper.rb

    config.fixture_path = "#{::Rails.root}/spec/fabricators"
    

    The second is that you are calling Fabricator instead of Fabricate in the before block of your spec. Fabricator is used to declare definitions and Fabricate is used to actually create an object.