简体   繁体   中英

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.

I have two factories, one for the role which has_many users and a user that belongs_to a role .

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

  factory :admin, traits: [:admin]
end

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.

require '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.

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. 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. 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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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