我无法解决如何让这些测试恢复绿色的问题。
模型
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: true
validates :zip, presence: true, format: { with: VALID_ZIP_REGEX }
validates_numericality_of :puzzle_pieces, only_integer: true
规格
it { should validate_presence_of(:email) }
it { should validate_uniqueness_of(:email) }
it { should allow_value('john.doe@example.com', 'alice@yahoo.ca').for(:email) }
it { should_not allow_value('john2example.com', 'john@examplecom').for(:email) }
it { should validate_presence_of(:zip) }
it { should allow_value('35124', '35124-1234').for(:zip) }
it { should_not allow_value('5124', '35124-12345').for(:zip) }
it { should validate_numericality_of(:puzzle_pieces).only_integer }
上述测试通过,直到我添加此自定义验证。
自定义验证器
class PiecesValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value > 0 && value <= Puzzle.remaining
record.errors[attribute] << (options[:message] || "Puzzle pieces must be between 1 and #{Puzzle.remaining}")
end
end
end
模型
validates :puzzle_pieces, pieces: true
规格
it "does not allow a negative number of puzzle pieces to be saved" do
order = build(:order, puzzle_pieces: -1)
expect(order).to be_invalid
end
最后一次测试通过了,但是我的所有测试都失败并且出现了相同的错误
NoMethodError:
undefined method `>' for nil:NilClass
我不明白如何解决这个问题。看来,shoulda测试在隔离状态下运行得很好。但是当添加自定义验证时,它们都会爆炸。
任何帮助我理解这一点的帮助都将非常感谢!
答案 0 :(得分:3)
您的问题是您的验证不期望value
为零。将您的方法更改为:
class PiecesValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value && value > 0 && value <= Puzzle.remaining
record.errors[attribute] << (options[:message] || "Puzzle pieces must be between 1 and #{Puzzle.remaining}")
end
end
end
如果验证字段为空,则不会添加错误。但是,您可以使用标准rails验证器来实现您的目标:
validates :puzzle_pieces, numericality: { only_integer: true, less_then: Puzzle.remaining, greater_then: 0 }