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
使用 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