3

我有简单的模型:

class Category < ActiveRecord::Base
  belongs_to :board
  validates :name, presence: true, uniqueness: {scope: :board_id}
  validates :board, presence: true
  validates :display_order, presence: true, uniqueness: {scope: :board_id}

  before_save :set_display_order

  private

  def set_display_order
    last = self.board.categories.order("display_order DESC").last
    self.display_order = last.display_order + 100 if last
  end
end

当我添加这个 before_save 回调时,这些测试开始失败:

  it { should validate_uniqueness_of(:display_order).scoped_to(:board_id) }
  it { should validate_uniqueness_of(:name).scoped_to(:board_id) }

有错误(如果私有方法中的行last = ...):

 NoMethodError:
   undefined method `categories' for nil:NilClass

其他应该测试工作正常:

  it { should validate_presence_of(:name) }
  it { should validate_presence_of(:board) }
  it { should belong_to :board }

知道这里有什么问题吗?我试图改变before_savebefore_validation但还是一样。

4

2 回答 2

2

因为应该在数据库中创建记录。Gem 创建记录跳过验证

http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/Shoulda/Matchers/ActiveModel#validate_uniqueness_of-instance_method Ensures that the model is invalid if the given attribute is not unique. It uses the first existing record or creates a new one if no record exists in the database. It simply uses ':validate => false' to get around validations, so it will probably fail if there are 'NOT NULL' constraints. In that case, you must create a record before calling 'validate_uniqueness_of'.

在您的情况下,createdcategory是空的,这意味着您从 nilcategory.board # => nil调用方法。categories

您应该自己创建一个记录以进行唯一性测试。

于 2013-10-16T18:23:33.897 回答
1

解决 shoulda_matchers 和 AR 回调限制的一种方法是重新定义 shoulda 匹配器使用的测试主题。

例子:

# category_spec.rb

# assuming you're using factorygirl and have this setup correctly
let(:board) { FactoryGirl.create(:board, :with_many_categories) }
subject { FactoryGirl.build(:category, board: board) }

# your shoulda matcher validations here
于 2015-09-10T17:02:40.707 回答