简单答案:使用 factory.sequence
如果您有一个需要唯一的字段,您可以在 factory_girl 中添加一个序列以确保它永远不会相同:
Factory.define :user do |user|
sequence(:email){|n| "user#{n}@factory.com" }
user.password{ "secret" }
end
这将每次增加n,以便生成一个唯一的电子邮件地址,例如user52@factory.com。 (更多信息请参见https://github.com/thoughtbot/factory_girl/wiki/Usage)
但是这在 Rails.env.development 中并不总是很好...
随着时间的推移,我发现这实际上并不是创建唯一电子邮件地址的最有用方法。原因是,虽然工厂对于您的测试环境总是独一无二的,但对于您的开发环境并不总是独一无二的,n 在您启动和关闭环境时会自行重置。在:test 中这不是问题,因为数据库已被擦除,但在:development 中,您倾向于将相同的数据保留一段时间。
然后您会遇到冲突并发现自己不得不手动将电子邮件覆盖为您知道是独特的东西,这很烦人。
通常更有用:使用随机数
由于我定期从控制台调用u = Factory :user,因此我改为生成一个随机数。你不能保证避免碰撞,但实际上它几乎不会发生:
Factory.define :user do |user|
user.email {"user_#{Random.rand(1000).to_s}@factory.com" }
user.password{ "secret" }
end
注意您必须使用 Random.rand 而不是 rand() 因为 FactoryGirl 中的冲突(错误?)[https://github.com/thoughtbot/factory_girl/issues/219](see 这里)。
这使您可以从命令行随意创建用户,而不管数据库中是否已经存在工厂生成的用户。
使电子邮件测试更容易的可选附加功能
当您进行电子邮件测试时,您通常希望验证特定用户的操作是否触发了发送给其他用户的电子邮件。
您以Robin Hood 登录,发送电子邮件至Maid Marion,然后前往您的收件箱进行验证。您在收件箱中看到的内容来自user_842@factory.com。那到底是谁?
您需要返回您的数据库以检查电子邮件是否由您预期的任何人发送/接收。再一次,这有点痛苦。
我喜欢做的是使用工厂用户的名称和随机数生成电子邮件。这使得检查东西来自谁变得容易得多(并且也使碰撞几乎不可能消失)。使用 Faker gem (http://faker.rubyforge.org/) 创建我们得到的名称:
Factory.define :user do |user|
user.first_name { Faker::Name::first_name }
user.last_name { Faker::Name::last_name }
user.email {|u| "#{u.first_name}_#{u.last_name}_#{Random.rand(1000).to_s}@factory.com" }
end
最后,由于 Faker 有时会生成对电子邮件不友好的名称(Mike O'Donnell),我们需要将可接受的字符列入白名单:.gsub(/[^a-zA-Z1-10]/, '')
Factory.define :user do |user|
user.first_name { Faker::Name::first_name }
user.last_name { Faker::Name::last_name }
user.email {|u| "#{u.first_name.gsub(/[^a-zA-Z1-10]/, '')}_#{u.last_name.gsub(/[^a-zA-Z1-10]/, '')}_#{Random.rand(1000).to_s}@factory.com" }
end
这为我们提供了风度翩翩但独特的电子邮件,例如 robin_hood_341@factory.com 和 maid_marion_10@factory.com