【问题标题】:Faker is producing duplicate data when used in factory_girlFaker 在 factory_girl 中使用时会产生重复数据
【发布时间】:2011-07-18 09:39:42
【问题描述】:

我正在尝试使用 Faker gem 将一些虚假数据填充到工厂中:

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 gem 为每个用户生成新名称,而不仅仅是重复使用原来的名称?

【问题讨论】:

  • 只是在黑暗中拍摄,但您是否尝试过使用 user.sequence(:first_name} {|n| Faker::Name::first_name} 之类的东西? FactoryGirl 可能只是在加载您的“夹具”时评估您的 Faker 调用。使用sequence param,&amp;block 方法应该可以防止这种情况发生。

标签: ruby-on-rails factory-bot


【解决方案1】:
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

尝试在伪造者周围加上括号。见this link

【讨论】:

  • 我非常喜欢 stackoverflow - 谢谢你,你救了我的培根
  • 谢谢,这解决了我的问题!
  • 为什么,为什么,为什么?这是怎么回事?
  • 因为“惰性属性”,见:github.com/thoughtbot/factory_girl/blob/master/…
  • 遗憾的是,这并不总是有效。这基本上只是得到一个新的随机伪造者对象,但是由于 RNG,仍有可能失败。
【解决方案2】:

请注意,由于可用的假数据数量有限,Faker 可能仍会提供重复数据。

为了简单的测试目的并通过唯一性验证,我使用了以下内容:

sequence(:first_name) {|n| Faker::Name::first_name + " (#{n})"}
sequence(:last_name) {|n| Faker::Name::last_name + " (#{n})"}

【讨论】:

  • 这个答案值得更多的支持。当您的测试创建大量实例时,可能会发生这种情况。
  • 是的,我同意 Enrico 的观点。 +1
  • 好主意,但是如果您使用名字和姓氏来生成电子邮件,或者您对格式进行了验证(不知道任何有括号的名称:P )。
【解决方案3】:

为了保留正确答案,这里转载自博客,我不相信答案。

如果你使用下面的代码,faker 不会产生唯一的名字

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

但是在 faker 周围加上花括号就可以了!

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

为了解释原因,第一个示例是生成相同的名称。它只评估一次。第二个示例在每次使用工厂时进行评估。

这是由于 {} 提供了惰性求值。本质上,他们提供了一个带有 Faker 调用作为返回值的 proc/lambda。

【讨论】:

  • 感谢您发布此信息。我不明白为什么 Faker 无法生成随机数据,而且我遇到的每个示例似乎都展示了如何使用排序,这对我来说似乎很奇怪。我想使用 Faker,所以每条记录都是随机的,而不是排序的。只需在我的 Faker 调用周围添加大括号即可解决问题。简洁大方!
【解决方案4】:

当您对属性进行唯一性验证时,使用序列的一种(效率较低)替代方法是检查建议的值是否已经存在并继续尝试新的值直到它唯一为止:

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

【讨论】:

    猜你喜欢
    • 2015-09-11
    • 2016-05-11
    • 1970-01-01
    • 2019-04-11
    • 2019-04-29
    • 2023-03-30
    • 1970-01-01
    • 2021-12-12
    • 2017-01-25
    相关资源
    最近更新 更多