如果在describe块中调用,为什么Factory Girl会创建重复项

时间:2013-06-27 18:32:39

标签: rspec factory-bot faker

我正在使用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

3 个答案:

答案 0 :(得分:2)

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

Why isn't factory_girl operating transactionally for me? - rows remain in database after tests

工厂结果证明不是交易性的。在spec_helper.rb的以下行之后问题消失了:

config.use_transactional_fixtures = true

答案 1 :(得分:2)

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

config.use_transactional_fixtures = true

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

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

不适用于:

auth_token Faker::Lorem.characters(32)

答案 2 :(得分:0)

Faker最终仍会生成重复的电子邮件。您可以使用序列或检查电子邮件是否尚不存在。见Faker is producing duplicate data when used in factory_girl