4

我正在使用 Factory Girl 和 Faker 创建独特的测试用户。用户模型对电子邮件进行唯一性验证。

如果我嵌套 2 级描述块,那么一些测试将失败,因为有重复的电子邮件。如果我不嵌套描述块,那么所有工厂调用都会返回唯一用户并且测试通过。

为什么 Faker 在第一种情况下会生成重复的电子邮件?

#factories/user.rb

# a simple factory with Faker
FactoryGirl.define do
  factory :student, class: User do
    first_name { Faker::Name.first_name }
    last_name { Faker::Name.last_name }
    password { Faker::Lorem.words(3).join }
    email { Faker::Internet.email }
  end
end

#spec/models/user_spec.rb   

# in this test structure, Faker returns duplicate emails
describe "nested describe blocks" do
  describe "block 1" do
    it "creates faker duplicates" do 
      10.times{
        FactoryGirl.create(:student)
      }
    end
   end
  describe "block 2" do 
    it "creates faker duplicates" do 
      10.times{
        FactoryGirl.create(:student)
      }
    end
  end
end

# in this structure, Faker emails are unique
describe "no nested describe blocks" do     
  it "doesn't create duplicates" do 
    10.times{
      FactoryGirl.create(:student)
    }
  end      
  it "doesn't create duplicates" do
    10.times{
      FactoryGirl.create(:student)
    }
  end      
end

Rspec 返回以下错误:

Failure/Error: FactoryGirl.create(:student)
 ActiveRecord::RecordInvalid:
   Validation failed: Email has already been taken, Email has already been taken, Authentication token has already been taken
4

3 回答 3

3

在把我的头敲在桌子上几个小时后,我的同事找到了答案:

为什么 factory_girl 不为我进行交易操作?- 测试后行保留在数据库中

事实证明,这些工厂不是交易型的。该问题在 spec_helper.rb 的以下行之后消失了:

config.use_transactional_fixtures = true
于 2013-06-29T00:39:24.073 回答
3

@Dyanisse 正如你所说,我们需要在 spec_helper.rb 中进行以下配置

config.use_transactional_fixtures = true

但仅此还不够。我们需要将它添加到大括号中以重新评估它,如下所示

auth_token { Faker::Lorem.characters(32) }

它不适用于:

auth_token Faker::Lorem.characters(32)
于 2015-06-15T11:00:19.793 回答
0

Faker 最终仍会生成重复的电子邮件。您可以使用序列或检查电子邮件是否尚不存在。见Faker 在 factory_girl 中使用时产生重复数据

于 2015-11-06T21:28:14.500 回答