验证前使用模型设置器时出现 shoulda-matchers 错误
shoulda-matches error when using model setters before validarion
我有订单模型,其中包含用于计算用户订购的产品总价的行
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) }
不幸的是我收到以下错误
Failure/Error: it { 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.
我该如何解决这个问题?
使用 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
设置为非零值。这就是您收到此错误的原因。
所以你真的不需要验证或匹配器,因为两者都不会失败。
我有订单模型,其中包含用于计算用户订购的产品总价的行
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) }
不幸的是我收到以下错误
Failure/Error: it { 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.
我该如何解决这个问题?
使用 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
设置为非零值。这就是您收到此错误的原因。
所以你真的不需要验证或匹配器,因为两者都不会失败。