I'm using FactoryBot and Faker for my tests, and it looks like that Faker is generating the same name:
class Profile < ApplicationRecord
belongs_to :user
validates_presence_of :first_name, :last_name, :nickname
validates :nickname, uniqueness: { case_sensitive: false }
end
FactoryBot.define do
factory :user do
sequence(:email) { |n| "user#{n}@example.org" }
password "123456"
trait :with_profile do
profile
end
end
end
FactoryBot.define do
factory :profile do
first_name Faker::Name.unique.first_name
last_name Faker::Name.unique.last_name
nickname { "#{first_name}_#{last_name}".downcase }
user
end
end
RSpec.feature "Friendships", type: :feature do
scenario "User can accept a pending friendship request" do
@tom = create(:user, :with_profile)
@jerry = create(:user, :with_profile)
#other stuff
end
end
Even I'm using the unique method, I'm getting the error
ActiveRecord::RecordInvalid: Validation failed: Nickname has already been taken`.
Any clues?
Should be:
first_name { Faker::Name.unique.first_name }
last_name { Faker::Name.unique.last_name }
When loading Faker::Name.unique.first_name
will be evaluated. Threfore, use blocks.
Edit:
FactoryBot.define do
factory :profile do
first_name Faker::Name.unique.first_name
end
end
In this example Faker::Name.unique.first_name
will be evaluated once, during the factory definition (when the file is loaded/required). If it finds a unique value, say 'John Doe' it's will be used for each item created by this factory.
Or in other words: after the file is loaded, and Faker::Name.unique.first_name
evaluated you may think of this factory as if it was:
FactoryBot.define do
factory :profile do
first_name 'John Doe'
end
end
When you use blocks - the block's body will be evaluated each time you call create(:profile)
or build(:profile)
. The Faker::Name.unique.first_name
part inside the block will be called each time, and return different, unique results.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With