assert_equal says <0.15> expected but was <0.15>, but only if the method computes 0.15 in a certain way
So for this model method:
def tax_rate
tax_rate = 0.0
tax_rate += STATE_TAX if state_taxable? #STATE_TAX = 0.1
tax_rate += IMPORT_TAX if imported? #IMPO开发者_运维问答RT_TAX = 0.05
tax_rate
end
This test fails:
@item.update_attributes({:state_taxable => true,
:imported => true,
:price => 32.19})
assert_equal 0.15, @item.tax_rate
I get this error:
<0.15> expected but was <0.15>.
However, this test will pass:
@item.update_attributes({:state_taxable => true,
:imported => false,
:price => 14.99})
assert_equal 0.1, @item.tax_rate
So I get the error when tax_rate does 0.0 + 0.1 + 0.05, but not when it does 0.0 + 0.1, or 0.0 + 0.05. Both 0.15s are Floats, so I don't see what could be causing this. I've spent too long mulling over this, hopefully someone can point out what the culprit is. Thanks in advance guys.
Floating-point numbers can't be represented exactly; what you need to do is use assert_in_delta
to check you're within a specified range.
Something like assert_in_delta 0.15, @item.tax_rate, 0.001
should do it: it'll check you're within 0.001 of the expected value.
IMHO, you should store such things as a integer numbers (in cents).
I have had this error many times and it's been because they were different classes.
Try
assert_equal 0.15.class, @item.tax_rate.class
And I am sure it will say something like
<float> expected but was <double>.
If you do
assert_equal 0.15.to_float, @item.tax_rate.to_float
It'll probably pass
0.1
, along with other numbers, cannot be represented exactly in floating-point arithmetics. Hence, you should use something like (I'm no Ruby guy):
assert_true abs(0.15 - @item.tax_rate) < 0.0001
And generally speaking, you shouldn't really be using floats for money/currency: there are a lot of really nasty subtle issues that will lose money between the cracks. See this question.
精彩评论