Faker создает дубликаты данных при использовании в factory_girl - PullRequest
85 голосов
/ 18 марта 2011

Я пытаюсь заполнить некоторые фальшивые данные на фабрике, используя гем Faker:

Factory.define :user do |user|
  user.first_name Faker::Name::first_name
  user.last_name Faker::Name::last_name
  user.sequence(:email) {|n| "user#{n}@blow.com" }
end

Однако, хотя я ожидаю, что это произведет пользователей, которые имеют разные имена и фамилии, все они одинаковы:

>> Factory(:user)
=> #<User id: 16, email: "user7@blow.com", created_at: "2011-03-18 18:29:33",     
updated_at: "2011-03-18 18:29:33", first_name: "Bailey", last_name: "Durgan">
>> Factory(:user)
=> #<User id: 17, email: "user8@blow.com", created_at: "2011-03-18 18:29:39", 
updated_at: "2011-03-18 18:29:39", first_name: "Bailey", last_name: "Durgan">

Как я могу заставить гем Faker генерировать новые имена для каждого пользователя, а не просто повторно использовать оригинальные?

Ответы [ 4 ]

154 голосов
/ 18 марта 2011
Factory.define :user do |user|
  user.first_name { Faker::Name::first_name }
  user.last_name { Faker::Name::last_name }
  user.sequence(:email) {|n| "user#{n}@blow.com" }
end

Попробуйте поставить скобки вокруг мошенников.см эту ссылку

43 голосов
/ 03 июля 2014

Обратите внимание, что Faker может по-прежнему предоставлять дубликаты данных из-за ограниченного количества доступных поддельных данных.

Для простых целей тестирования и проверки достоверности уникальности я использовал следующее:

sequence(:first_name) {|n| Faker::Name::first_name + " (#{n})"}
sequence(:last_name) {|n| Faker::Name::last_name + " (#{n})"}
17 голосов
/ 14 апреля 2014

Ради сохранения правильного ответа, здесь оно перенесено из блога, я не беру на себя ответственность за ответ.

Если вы воспользуетесь приведенным ниже кодом, фейкер не будет выдавать уникальныйИмена

Factory.define :user do |u|
  u.first_name Faker::Name.first_name
  u.last_name Faker::Name.last_name
end

Однако использование фигурных скобок вокруг фейкера заставляет его работать!

Factory.define :user do |u|
  u.first_name { Faker::Name.first_name }
  u.last_name { Faker::Name.last_name }
end

Чтобы объяснить, почему в первом примере создаются те же имена,Это только оценка один раз.Второй пример оценивает каждый раз, когда используется фабрика.

Это связано с тем, что {} обеспечивает ленивую оценку.По сути, они предоставляют proc / lambda вызов Faker в качестве возвращаемого значения.

4 голосов
/ 07 ноября 2015

(менее эффективная) альтернатива использованию последовательностей, когда у вас есть проверка уникальности атрибута, состоит в том, чтобы проверить, существует ли уже предложенное значение, и продолжать пробовать новые, пока оно не станет уникальным:

FactoryGirl.define do
  factory :company do
    name do
      loop do
        possible_name = Faker::Company.name
        break possible_name unless Company.exists?(name: possible_name)
      end
    end
  end
end
...