当在factory_girl中使用时,Faker正在生成重复数据

Pet*_*xey 85 ruby-on-rails factory-bot

我正在尝试使用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
Run Code Online (Sandbox Code Playgroud)

但是,虽然我希望这会生成具有不同first_name和last_names的用户,但每个用户都是相同的:

>> 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">
Run Code Online (Sandbox Code Playgroud)

如何让Faker gem为每个用户生成新名称,而不仅仅重用原始用户?

Wil*_*Ayd 154

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
Run Code Online (Sandbox Code Playgroud)

尝试在支架周围放置支架.看到这个链接

  • 我非常喜欢stackoverflow - 谢谢Will,你救了我的培根 (8认同)
  • 可悲的是,这并不总是有效.这基本上只是获得一个新的随机faker对象,但是由于RNG,它仍然有可能失败. (8认同)
  • 为什么,为什么,为什么?这里发生了什么? (5认同)
  • 因为"懒惰属性",请参阅:https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#lazy-attributes (4认同)

Twi*_*ceB 43

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

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

sequence(:first_name) {|n| Faker::Name::first_name + " (#{n})"}
sequence(:last_name) {|n| Faker::Name::last_name + " (#{n})"}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案值得更多的赞成.当您的测试创建大量实例时,可能会发生这种情况. (3认同)

oco*_*odo 17

为了保留正确的答案,这里它是从博客中转移出来的,我不赞成答案.

如果您使用下面的代码,faker将不会生成唯一的名称

Factory.define :user do |u|
  u.first_name Faker::Name.first_name
  u.last_name Faker::Name.last_name
end
Run Code Online (Sandbox Code Playgroud)

然而,在faker周围放置花括号使它工作!

Factory.define :user do |u|
  u.first_name { Faker::Name.first_name }
  u.last_name { Faker::Name.last_name }
end
Run Code Online (Sandbox Code Playgroud)

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

这是由于{}提供了懒惰的评估.基本上他们提供了一个带有Faker调用的proc/lambda作为返回值.


Dan*_*ohn 5

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

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
Run Code Online (Sandbox Code Playgroud)