Ruby on rails Factory Girl自加入验证错误

Ruby on rails Factory Girl自加入验证错误,ruby-on-rails,testing,rspec,factory-bot,ruby-on-rails-5,Ruby On Rails,Testing,Rspec,Factory Bot,Ruby On Rails 5,我正在尝试测试一个系统,该系统用于创建在publications表上有自连接的文章翻译。我创建了一个工厂,它将创建多个翻译,并将它们与“父”文章关联 将Rails 5与factory_girl 4.7.0、rspec和数据库_cleaner配合使用 所有操作都按预期工作,但创建测试是问题所在 以下是相关的模型验证和方法: # models/publication.rb has_many :translations, class_name: "Publication", foreign_

我正在尝试测试一个系统,该系统用于创建在publications表上有自连接的文章翻译。我创建了一个工厂,它将创建多个翻译,并将它们与“父”文章关联

将Rails 5与factory_girl 4.7.0、rspec和数据库_cleaner配合使用

所有操作都按预期工作,但创建测试是问题所在

以下是相关的模型验证和方法:

  # models/publication.rb

  has_many :translations, class_name: "Publication", foreign_key: "translation_id", dependent: :nullify
  belongs_to :translation, class_name: "Publication", optional: true

  validates :language, uniqueness: { scope: :translation_id }, if: :is_translation?

  def is_translation?
    !translation.nil?
  end
工厂(不相关代码省略):

还有一个基本测试:

    # spec/models/publication_spec.rb
    before(:each) do
      @translation_parent = create(:publication, :with_translations)
      @pub_without_trans = create(:publication, :with_random_user)
    end

    scenario 'is_translation?' do
      # No actual test code needed, this passes regardless
    end

    scenario 'has_translations?' do
      # No actual test code needed, this (and subsequent tests) fail regardless
    end
最后,错误是:

 Failure/Error: create_list(:translation, 3, {user: object.user, translation:object})

 ActiveRecord::RecordInvalid:
   Validation failed: Language has already been taken
第一个测试通过(并且正确创建了具有翻译的发布对象),但任何后续测试都失败。问题是,我将唯一性验证的范围限定为translation_id,而factorygirl似乎正试图将生成的翻译添加到现有的出版物中,而不是创建一个全新的出版物

感谢您的帮助

解决了

问题在于每次测试后,
翻译
工厂中的序列迭代器没有重置为0。所以在测试1之后,它开始尝试访问一个不存在的数组索引。在它再次这样做之后,它触发了验证,测试失败了

这个解决方案并不可爱,但目前已经足够好了

sequence(:language) do |iteration|
  array = ['FR', 'ES', 'DE', 'CN']
  # Returns a number between 0 and array.length
  array[iteration%array.length]
end
sequence(:title) do |iteration|
  array = ['French Article', 'Spanish Article', 'German Article', 'Chinese Article']
  # Returns a number between 0 and array.length
  array[iteration%array.length]
end
sequence(:language) do |iteration|
  array = ['FR', 'ES', 'DE', 'CN']
  # Returns a number between 0 and array.length
  array[iteration%array.length]
end
sequence(:title) do |iteration|
  array = ['French Article', 'Spanish Article', 'German Article', 'Chinese Article']
  # Returns a number between 0 and array.length
  array[iteration%array.length]
end