Rspec/FactoryGirl 大型测试套件中的唯一性验证

Rspec/FactoryGirl uniqueness validations in a large test suite

使用 Rspec 和 FactoryGirl,如果我有一个使用序列自动递增 trait 的工厂,并且在某些规范中,如果我明确设置了这个特性,并且有足够大的测试套件,有时随机规格失败

Validation failed: uniq_id has already been taken

工厂是这样定义的:

factory :user { sequence(:uniq_id) {|n| n + 1000} }

我猜这个验证失败是因为在我的测试套件的一个地方,我生成了一个这样的用户:

create(:user, uniq_id: 5555)

并且因为据推测 factory girl 正在通过套件生成超过 4,555 个用户,所以验证失败了?

我试图通过将 uniq_id 变成 55555(更大的数字)来避免这个问题,所以没有干扰。但是有更好的解决方案吗?我的 spec_helper 包括这些相关位:

config.use_transactional_fixtures = true

config.after(:all) do
  DatabaseCleaner.clean_with(:truncation)
end

我有时会遇到这种情况。我没有找到任何解释,但只发生在大数据集上。我让人去找解释!

发生这种情况时,您可以像这样声明您的属性(这里是使用 faker gem 的示例):

FactoryGirl.define do
  factory :user do
    login do 
      # first attempt
      l = Faker::Internet.user_name
      while User.exists?(:login => l) do
        # Here is a loop forcing validation
        l = Faker::Internet.user_name
      end
      l   # return login
    end
  end
end

我能够在我的工厂解决我的问题(基于@gotva 在问题评论中的建议)。

factory :user do
  sequence(:uniq_id) { |n| n + 1000 }
   # increment again if somehow invalid
   after(:build) do |obj|
     if !obj.valid? && obj.errors.keys.include?(:uniq_id)
       obj.uniq_id +=1
     end
   end
end