I am writing tests in Rspec with Factorybot.
When my test looks like this, it fails:
describe "The #add_admin function" do
context "with a normal user" do
let(:user) { create(:user) }
let(:role) { create(:admin_role) }
it "adds the admin role" do
expect(user.roles.map(&:name)).not_to include "admin"
user.make_admin
expect(user.roles.map(&:name)).to include "admin"
end
end
end
end
with the error stating
ActiveRecord::AssociationTypeMismatch:
Role(#13660) expected, got nil which is an instance of NilClass(#40)
Which says to me that the role doesn't exist yet
but like this, without changing anything, it passes:
describe "The #add_admin function" do
context "with a normal user" do
let(:user) { create(:user) }
let(:role) { create(:admin_role) }
it "adds the admin role" do
role
expect(user.roles.map(&:name)).not_to include "admin"
user.make_admin
expect(user.roles.map(&:name)).to include "admin"
end
end
end
end
Something like this makes me think I may be approaching the test wrong... The function that I'm testing looks like this:
class User < ApplicationRecord
has_many :user_roles, dependent: :destroy
has_many :roles, through: :user_roles
...
def make_admin
admin_role = Role.find_by(name: :admin)
roles << admin_role
end
end
My factories look like this:
users.rb
FactoryBot.define do
factory :user do
first_name { 'Joe' }
last_name { 'Schmo' }
email { Faker::Internet.email }
roles { [] }
trait :with_role do
transient do
role { nil }
end
roles { [association(:role, name:role)] }
end
trait :admin_user do
roles { [association(:admin_role)] }
end
end
end
roles.rb
FactoryBot.define do
factory :role do
name { Faker::Job}
end
factory :admin_role, class: Role do
name { "admin" }
end
end
I have seen this error/bug before on a different code base but I was working on legacy code and the idea was "do what works". Now im starting from scratch on a project and would like to eliminate the problem when its small.