【问题标题】:Rspec/FactoryGirl uniqueness validations in a large test suite大型测试套件中的 Rspec/FactoryGirl 唯一性验证
【发布时间】:2015-02-26 09:54:46
【问题描述】:

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

【问题讨论】:

  • 我认为您可以在工厂女孩回调中解决您的问题。例如,您可以检查after(:build) 回调中的唯一性值,如果存在具有此值的另一个用户,则再次触发sequence
  • @gotva 这听起来是个不错的解决方案。您可以发布答案并附上after(:build) 的示例代码吗?我不确定如何在块中使用序列,他们的文档没有说清楚。
  • @gotva 确实想出来了,而且效果很好。谢谢!添加作为答案,以便我可以接受并给你所有的分数。
  • 对不起,我现在没有机会测试工厂女孩 - 所以我怕我可以给出错误的代码。我给了你想法,你实现了它 - 将结果发布为答案并自己接受;)

标签: ruby-on-rails rspec factory-bot


【解决方案1】:

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

当它发生时,你可以像这样声明你的属性(这里是一个使用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

【讨论】:

    【解决方案2】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多