ruby-on-railsrspecfabrication-gem

Pass variables in fabricator gem and rspec


How would I create a user by passing a variable used as a transient in rspec? What am I doing wrong?

controller_tests_spec.rb

describe "GET index" do
  context "with admin user_role" do
    before(:each) do
      set_current_admin
      todo_list1 = Fabricate(:todo_list)
      todo_list2 = Fabricate(:todo_list)
      get :index
    end
    it "redirects to the todo lists path" do
      expect(response).to redirect_to todo_lists_path
    end
  end
end

/support/macros.rb

def set_current_admin(user=nil)
  session[:user_id] = (user || Fabricate(:user, role: "admin")).id
end

Fabricators

  # user_fabricator.rb
  Fabricator(:user) do
    email {Faker::Internet.email}
    password 'password'
    first_name {Faker::Name.first_name}
    last_name {Faker::Name.last_name}
    transient :role  
    user_role {Fabricate(:user_role, role: :role)}
  end

  # user_role_fabricator.rb
  Fabricator(:user_role) do
    role
  end

Solution

  • All processed values (including transients) are available through the attrs hash passed into each field as it is fabricated. I modified your fabricators to do what I think you are expecting.

    I defaulted the role field in :user_role to "member". The way you had it would try to expand to use another fabricator named role, which I don't think is what you want.

    # user_fabricator.rb
    Fabricator(:user) do
      email {Faker::Internet.email}
      password 'password'
      first_name {Faker::Name.first_name}
      last_name {Faker::Name.last_name}
      transient :role  
      user_role { |attrs| Fabricate(:user_role, role: attrs[:role]) }
    end
    
    # user_role_fabricator.rb
    Fabricator(:user_role) do
      role 'member'
    end