FactoryBot и Faker - уникальный не работает - PullRequest
0 голосов
/ 19 мая 2018

Я использую FactoryBot и Faker для своих тестов, и похоже, что Faker генерирует одно и то же имя:

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

Даже если я использую уникальный метод, я получаю ошибку

ActiveRecord::RecordInvalid: Validation failed: Nickname has already been taken`.

Есть какие-нибудь подсказки?

1 Ответ

0 голосов
/ 19 мая 2018

Должно быть:

first_name { Faker::Name.unique.first_name }
last_name { Faker::Name.unique.last_name }

При загрузке Faker::Name.unique.first_name будет оцениваться.Поэтому используйте блоки.

Редактировать:

FactoryBot.define do
  factory :profile do
    first_name Faker::Name.unique.first_name
  end
end

В этом примере Faker::Name.unique.first_name будет оцениваться один раз, во время определения фабрики (когда файл загружается / требуется).Если он находит уникальное значение, скажем «Джон Доу», оно будет использоваться для каждого элемента, созданного этой фабрикой.

Или другими словами: после загрузки файла и оценки Faker::Name.unique.first_name вы можете думать об этой фабрике, как если бы она была:

FactoryBot.define do
  factory :profile do
    first_name 'John Doe'
  end
end

Когда вы используете блоки - тело блокабудет оцениваться каждый раз, когда вы звоните create(:profile) или build(:profile).Часть Faker::Name.unique.first_name внутри блока будет вызываться каждый раз и возвращать разные уникальные результаты.

...