我有订单模型,其中包含用于计算用户订购产品总价格的行
before_validation :set_total!
validates :total, presence: true, numericality: { greater_than_or_equal_to: 0 }
set_total看起来像这样
def set_total!
self.total = products.map(&price).sum
end
根据我的规格,我正在尝试检查是否已实施总验证 TDD
it { should validate_presence_of(:total) }
it { should validate_numericality_of(:total).is_greater_than_or_equal_to(0) }
不幸的是我收到以下错误
失败/错误:它{should validate_presence_of(:total)}
Order did not properly validate that :total cannot be empty/falsy. After setting :total to ‹nil› -- which was read back as ‹#<BigDecimal:5634b8b81008,'0.0',9(27)>› -- the matcher expected the Order to be invalid, but it was valid instead. As indicated in the message above, :total seems to be changing certain values as they are set, and this could have something to do with why this test is failing. If you've overridden the writer method for this attribute, then you may need to change it to make this test pass, or do something else entirely.
我该如何解决这个问题?
答案 0 :(得分:1)
使用validate_presence_of
匹配器大致相当于手动编写此测试:
describe Order do
it "fails validation when total is nil" do
order = Order.new
order.total = nil
order.validate
expect(order.errors[:total]).to include("can't be blank")
order.total = 42
expect(order.errors[:total]).not_to include("can't be blank")
end
end
如果您要运行此测试,您会发现这会失败。为什么?因为在您的模型中,您在执行验证时将total
设置为非零值。这就是你收到这个错误的原因。
所以你真的不需要验证或匹配器,因为没有人会失败。