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

4

好的,我想测试需要管理员用户的功能,我正在尝试以管理员身份登录,但为了这样做,我需要有管理员用户。

以下是我的代码:

  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个回答

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

你会如何在 describe 中使用这个? - Matt Elhotiby
你是否正在寻找答案?FactoryGirl.create(:admin_user) - Marlin Pierce
未定义方法 `role=' for #User:0x007ff90e203f78 - Matt Elhotiby
更新我的问题,附加更多我所做的细节。 - Matt Elhotiby
我的错,我应该使用多对多关联。我会编辑答案。 - Marlin Pierce

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 的工作方式不太熟悉,不理解为什么你不能在调用 let(:user) { create :user } 后立即像 user.roles << role 一样编写代码,但将它放入 before(:each) 块或单独的 it "should ... " do 块中应该可以解决问题。


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) }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接