简体   繁体   English

Rails RSpec测试Factorybot返回符号

[英]Rails rspec testing factorybot returning symbol

I would like to see if users have authorization to certain pages in my application. 我想看看用户是否有权访问我的应用程序中的某些页面。 For this I am using rSpec and FactoryBot as my fixtures replacement. 为此,我使用rSpecFactoryBot作为我的灯具替换。

I have two factories, one for the role which has_many users and a user that belongs_to a role . 我有两个工厂,一个用于具有has_many用户的role ,一个用于belongs_to一个roleuser

Role factory 角色工厂

FactoryBot.define do
  factory :role do
    trait :admin do
      role_name 'admin'
    end
  end

  factory :admin, traits: [:admin]
end

User factory 用户工厂

FactoryBot.define do
  factory :user do

    association :role, factory: :admin
  end
end

I am using Pundit for authorizatin and the pundit matchers gem for the testing of pundit policies. 我正在使用Pundit进行Authorizatin,而使用Pundit Matchers来测试Pundit策略。

require 'rails_helper' 需要'rails_helper'

describe AccountPolicy do
  subject { described_class.new(user, account) }
  let (:account) { Account.create }

  context 'being an admin' do
    let(:user) { User.create(role: :admin) }

    it { is_expected.to permit_action([:index]) }
  end
end

Above is the policy written to see if the user, being an admin, can access the Accounts index. 上面是编写策略,以查看作为管理员的用户是否可以访问“帐户”索引。 When running rake I get the following error. 运行rake ,出现以下错误。

ActiveRecord::AssociationTypeMismatch:
Role(#70284397401400) expected, got :admin which is an instance of Symbol(#70284363589400)

I see that I am getting a type mismatch. 我看到类型不匹配。 However, I am not sure how to return the role as an active record object, which I think is what it is expecting from the looks of it, instead of a symbol. 但是,我不确定如何将角色作为活动记录对象返回,我认为这是它从其外观(而不是符号)中所期望的。 How can I achieve this? 我该如何实现?

I think part of your issue is in your architecture, but I'll address that at the bottom. 我认为您的问题的一部分在于您的体系结构,但我将在底部解决。

let(:user) { User.create(role: :admin) }

This is trying to set a role attribute to the symbol :admin. 这试图将角色属性设置为符号:admin。 Whereas you want to pass in an actual admin role object/record. 而您想传递一个实际的管理员角色对象/记录。

let(:admin_role) { Role.create(:admin) }
let(:user) { User.create(role: admin_role) }

However, your current user factory is setting the role factory to be the admin factory. 但是,您当前的用户工厂将角色工厂设置为管理工厂。 So all users created will be admins by default. 因此,默认情况下,所有创建的用户均为管理员。 You'll want to do more reading on FactoryBot to structure your factories for easier creation of certain types of users. 您将需要在FactoryBot上进行更多阅读,以构建工厂,以便更轻松地创建某些类型的用户。 Adding traits to the user model to create the correct role would help with your current architecture. 向用户模型添加特征以创建正确的角色将有助于您当前的体系结构。

Out of curiosity, why use a separate table for role if a User can only have one? 出于好奇,如果用户只能拥有一个角色,为什么还要使用一个单独的表? Why not use an enum column on User? 为什么不使用User上的enum列?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM