在FactoryBot定义中通过Rolify设置角色

32

我正在使用devise、rolify和cancan,同时在测试中使用RSpec和FactoryBot。目前我正在编写一些测试,并且希望为这些测试定义具有不同角色的用户。以下是我目前使用FactoryBot进行操作的猜测:

FactoryBot.define do
  factory :user do
    name 'Test User'
    email 'example@example.com'
    password 'please'
    password_confirmation 'please'
    # required if the Devise Confirmable module is used
    confirmed_at Time.now

    factory :admin do
        self.has_role :admin
    end

    factory :curator do
        self.has_role :curator
    end

    factory :super_admin do
        self.has_role :super_admin
    end
  end
end

以下是我编写的几个测试,似乎不正确:

require 'spec_helper'
describe "Pages" do
    subject { page }

    before do
        @newpage = FactoryBot.create(:page)
        @newpage.save
    end

    context 'not logged in' do
        it_behaves_like 'not admin'
    end

    context 'logged in' do

        context 'as user' do
            before do
                @user = FactoryBot.create(:user)
                sign_in @user
            end

            it_behaves_like 'not admin'
        end

        context 'as curator' do
            before do
                @curator = FactoryBot.create(:curator)
                sign_in @curator
            end

            it_behaves_like 'not admin'
        end

        context 'as admin' do
            before do
                @admin = FactoryBot.create(:admin)
                sign_in @admin
            end

            it_behaves_like 'admin'
        end

        context 'as super admin' do
            before do
                @super_admin = FactoryBot.create(:super_admin)
                sign_in @super_admin
            end

            it_behaves_like 'admin'
        end
    end
end

当我运行测试时,这些是我的错误:

1) Pages logged in as admin behaves like admin can show page 
 Failure/Error: Unable to find matching line from backtrace
 NoMethodError:
   undefined method `has_role=' for #<User:0x007f883384d178>
 Shared Example Group: "admin" called from ./spec/requests/pages_spec.rb:41
 # ./spec/requests/pages_spec.rb:37:in `block (4 levels) in <top (required)>'

2) Pages logged in as curator behaves like not admin can show page 
 Failure/Error: Unable to find matching line from backtrace
 ArgumentError:
   Factory not registered: curator
 Shared Example Group: "not admin" called from ./spec/requests/pages_spec.rb:32
 # ./spec/requests/pages_spec.rb:28:in `block (4 levels) in <top (required)>'

3) Pages logged in as super admin behaves like admin can show page 
 Failure/Error: Unable to find matching line from backtrace
 ArgumentError:
   Factory not registered: super_admin
 Shared Example Group: "admin" called from ./spec/requests/pages_spec.rb:50
 # ./spec/requests/pages_spec.rb:46:in `block (4 levels) in <top (required)>'

注意:FactoryBot 以前叫做 FactoryGirl

1个回答

64

我更倾向于使用FactoryBot的after(:create)回调函数来创建角色(也可以参考此问题中的Rolify)。

此外,has_role?方法用于检查用户是否拥有特定角色,要设置特定角色,应使用add_role方法。

FactoryBot.define do
  factory :user do
    name 'Test User'
    email 'example@example.com'
    password 'please'
    password_confirmation 'please'
    # required if the Devise Confirmable module is used
    confirmed_at Time.now

    factory :admin do
        after(:create) {|user| user.add_role(:admin)}
    end

    factory :curator do
        after(:create) {|user| user.add_role(:curator)}
    end

    factory :super_admin do
        after(:create) {|user| user.add_role(:super_admin)}
    end
  end
end

注意:FactoryBot 以前被称为 FactoryGirl。


谢谢,我下次会尝试这个方法。我已经开始使用另一种处理用户角色的方法了。 - Kevin K
还要看一下 before(:create),也可以工作,但是回调不同。 - Dennis Hackethal

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