I have this spec that checks for the expected number:
expect(animal_cost).to eq(0.7771118644067795e5)
I get an error that says:
expected: 77711.18644067795
got: 0.7771118644067795e5
As you can see, the number I got is the same as the one I expected so I'm confused why this is failing. How can I set the spec?
animal_cost.class
is a BigDecimal.
expect (message).to eq "Hello World!" The keyword eql is an RSpec “matcher”. Here, we will introduce the other types of matchers in RSpec. Matchers to test for object or value equality.
RSpec is a mature, feature-packed testing framework, but the documentation can be difficult to navigate. As an alternative to the official documentation, this cheat sheet contains short example code to demonstrate all the built-in expectation matchers. These examples were created with RSpec 3.5.
Decimal numbers are the standard form of representing integers and non-integer numbers. When you compare the decimals, you need to check the digits before the decimal point and check if they are smaller than or greater than the other number.
For examples of RSpec.describe, it, let, etc., see the previous post: RSpec::Core Cheat Sheet. These are the most commonly used matchers. RSpec.describe 'Common, built-in expectation matchers' do example 'Equality' do expect('x'+'y').to eq('xy') # a == b expect('x'+'y').to eql('xy') # a.eql?
The best way to verify floats using rspec is to use the be_within
matcher. Floats cannot be represented completely mathematically accurate in binary. There are bound to be some rounding errors.
In your case one would write:
expect(animal_cost).to be_within(0.001).of(0.7771118644067795e5)
[animal_cost] equals
0.7771118644067795e5
[...] it's aBigDecimal
It's a floating point issue. Your BigDecimal
with a value of 0.7771118644067795e5 has an exact value of:
77711.18644067795
The float 77711.18644067795
on the other hand has an actual value of: (like most languages, Ruby truncates floats)
77711.186440677949576638638973236083984375
Depending on the comparison, these values might or might not be treated as "equal":
d = BigDecimal('0.7771118644067795e5')
f = 0.7771118644067795e5
d == f #=> true
f == d #=> true
d.eql?(f) #=> true
f.eql?(d) #=> false
The latter returns false
because that's how Float#eql?
works:
eql?(obj) → true or false
Returns
true
only ifobj
is aFloat
with the same value asfloat
.
In order to make the test pass with the exact value, you should use a BigDecimal
instead of a float:
expect(animal_cost).to eq(BigDecimal('0.7771118644067795e5'))
Personally, I'd avoid such examples because you're (apparently) copying the result into the expectation. It's not at all obvious whether this value is correct or not. (a "cost" with 11 decimal places seems wrong to me) Try to change your example data to get a comprehensible result and maybe also a "whole" number like e.g. 70,000.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With