如何使用Factory girl创建管理员角色?

时间:2012-04-12 20:56:23

标签: ruby-on-rails ruby ruby-on-rails-3 rspec factory-bot

好的,所以我想测试需要管理员用户的功能,我想尝试以管理员身份登录,但为了做到这一点,我需要一个管理员用户

这是我的代码

  let(:user) { FactoryGirl.create(:user) }
  let(:admin_role) { FactoryGirl.create(:role) }

FactoryGirl.define do
  factory :user do
    first_name "John"
    last_name  "Doe"
    email  "john@doe.com"
  end

  factory :role do
    name "Admin"
  end
end

如何连接它们我尝试了user.roles << user_role但是出现了这个错误

/Users/matt/Sites/application/spec/controllers/directory_controller_spec.rb:16:in `block (3 levels) in <top (required)>': undefined local variable or method `user' for #<Class:0x007fa550890d80> (NameError)

这是我的模特

class User < ActiveRecord::Base
    has_many :roles, :through => :role_users
    has_many :role_users
    ...

class Role < ActiveRecord::Base
    has_many :users, :through => :role_users
    has_many :role_users
    ...

class RoleUser < ActiveRecord::Base
    belongs_to :role
    belongs_to :user
end

3 个答案:

答案 0 :(得分:8)

spec/factories/user.rb

FactoryGirl.define do
  factory :user do
    first_name "John"
    last_name  "Doe"
    email "john@doe.com"
  end

  factory :admin_user, :parent => :user do
    roles { [ FactoryGirl.create(:admin_role) ] }
  end

  factory :role do
    name { "Role_#{rand(9999)}" }
  end

  factory :admin_role, :parent => :role do
    name "Admin"
  end
end

答案 1 :(得分:0)

解决

Factory.sequence(:email) {|n| "person#{n}@example.com" }

Factory.define :role do |r|
  r.name {"Admin"}
end

Factory.define :role_user do |ru|
  ru.association(:role)
  ru.association(:user)
end

Factory.define :user do |u|
  u.first_name {"matt"}
  u.last_name {"jones"}
  u.email {Factory.next(:email)}
end

并使用它

  let(:role_user) { FactoryGirl.create(:role_user)  }
  before { sign_in(role_user) }

答案 2 :(得分:0)

我遇到了完全相同的问题,代码如下:

describe "..." do
  let(:user) { create :user }
  let(:manager) { create :manager_role }
  user.roles << manager

  it "should ...." do
    # etc.
  end

end

# run rspec...
# => `block (2 levels) in <top (required)>': undefined local variable or method `user' for #<Class:0x000001016a2dc0> (NameError)

当我将user.roles << manager代码移动到before(:each)块时,错误消失了。因此,像:

describe "..." do
  let(:user) { create :user }
  let(:manager) { create :manager_role }

  before(:each) do
    user.roles << manager
  end

  it "should ...." do
    # etc.
  end

end

这样可以省去必须在工厂中指定role <-> user关联的痛苦。

我对rspec和factory_girl如何解决为什么在调用user.roles << role之后不能立即拥有let(:user) { create :user }之类的代码,而是将其置于before(:each)块中的方式不够熟悉或者进入一个单独的it "should ... " do块就可以了。