Hello
How can I test equality with two objects when they include some
attribute that is BigDecimal?
if I make something like this:
it “should …whatever” do
obj = Factory.create(:my_object)
…
MyObject.first.should == obj
end.
FAILS
This fails because the object expected is different from the object
gotten, and the only difference are the BigDecimal attributes, that are
different objects, even though they have the same value.
Thanks.
On Jul 8, 2010, at 5:04 AM, Juanma C. wrote:
end.
FAILS
This fails because the object expected is different from the object
gotten, and the only difference are the BigDecimal attributes, that are
different objects, even though they have the same value.
rspec delegates ==() to the objects being compared. It’s up to library
providers and users to override ==() in a way that is sane in a given
context. Assuming a single BigDecimal attr named amount, something like
this:
def ==(other)
self.attributes.merge(:amount => BigDecimal.new(self.amount.to_s)) ==
other.attributes.merge(:amount => BigDecimal.new(other.amount.to_s))
end
HTH,
David
David C. wrote:
On Jul 8, 2010, at 5:04 AM, Juanma C. wrote:
end.
FAILS
This fails because the object expected is different from the object
gotten, and the only difference are the BigDecimal attributes, that are
different objects, even though they have the same value.
rspec delegates ==() to the objects being compared. It’s up to library
providers and users to override ==() in a way that is sane in a given
context. Assuming a single BigDecimal attr named amount, something like
this:
def ==(other)
self.attributes.merge(:amount => BigDecimal.new(self.amount.to_s)) ==
other.attributes.merge(:amount => BigDecimal.new(other.amount.to_s))
end
HTH,
David
Thanks for your answer David, but I think there is a problem.
The assertion that fails has nothing to do with the BidDecimal types,
but with the created_at and updated_at timestamps
I have try this:
v = Factory.create(:my_object)
f = MyObject.first
v.should == f ==> This fails
v.amount.should == f.amount ==> This works
But…
v.updated_at.should == f.updated_at
RSpec::Expectations::ExpectationNotMetError: expected: Fri, 09 Jul 2010
06:57:48 UTC +00:00,
got: Fri, 09 Jul 2010 06:57:48 UTC +00:00 (using ==)
Diff:
from
/home/jmcervera/.rvm/gems/ruby-1.8.7-p299@rails3/gems/rspec-expectations-2.0.0.beta.15/lib/rspec/expectations/fail_with.rb:29:in
fail_with' from /home/jmcervera/.rvm/gems/ruby-1.8.7-p299@rails3/gems/rspec-expectations-2.0.0.beta.15/lib/rspec/matchers/operator_matcher.rb:39:in
fail_with_message’
from
/home/jmcervera/.rvm/gems/ruby-1.8.7-p299@rails3/gems/rspec-expectations-2.0.0.beta.15/lib/rspec/matchers/operator_matcher.rb:61:in
__delegate_operator' from /home/jmcervera/.rvm/gems/ruby-1.8.7-p299@rails3/gems/rspec-expectations-2.0.0.beta.15/lib/rspec/matchers/operator_matcher.rb:51:in
eval_match’
from
/home/jmcervera/.rvm/gems/ruby-1.8.7-p299@rails3/gems/rspec-expectations-2.0.0.beta.15/lib/rspec/matchers/operator_matcher.rb:29:in
`==’
from (irb):41
The updated_at has class ActiveSupport::TimeWithZone
v.updated_at.should == f.updated_at fails
v.updated_at.to_datetime.should == f.to_datetime.updated_at fails
v.updated_at.to_s.should == f.updated_at.to_s works
v.updated_at.to_i.should == f.updated_at.to_i works
And adding this method to the model doesn’t work either.
def ==(other)
(self.attributes.merge(:created_at =>
Datetime.new(self.created_at.to_s),
:updated_at =>
Datetime.new(self.updated_at.to_s)) ==
(other.attributes.merge(:created_at =>
Datetime.new(self.other_at.to_s),
:updated_at =>
Datetime.new(self.other_at.to_s))
end
Thanks
Juanma