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
4

3 に答える 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
于 2012-04-12T21:05:39.660 に答える
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

于 2012-05-10T17:56:51.213 に答える
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) }
于 2012-04-13T14:39:32.560 に答える