Search code examples
ruby-on-rails-3rspeccontrollerbigdecimal

Get rspec controller test to do a shallow comparison of BigDecimals


I have an rspec controller with the test:

it "assigns all rate_card_details as @rate_card_details" do
  rate_card_detail = FactoryGirl.create(:rate_card_detail)
  get :index, {}, valid_session
  assigns(:rate_card_details).should eq([rate_card_detail])
end

For most models, this works fine. However, in this case, the rate field is a decimal. This causes the rspec comparison to (for some reason) compare 1 instance of BigDecimal with another, including its location in memory. Here is the error:

 Failure/Error: assigns(:rate_card_details).should eq([rate_card_detail])

   expected: [#<RateCardDetail rate_card_id: 1, item_id: 1, rate: #<BigDecimal:7f82dcdb0ae0,'0.6941E2',18(18)>, created_at: "2013-06-05 18:12:53", updated_at: "2013-06-05 18:12:53">]
        got: [#<RateCardDetail rate_card_id: 1, item_id: 1, rate: #<BigDecimal:7f82dc9a74d0,'0.6941E2',18(18)>, created_at: "2013-06-05 18:12:53", updated_at: "2013-06-05 18:12:53">]

The 2 BigDecimals have the same value, but are different objects. Is there a way to get rspec to treat these as equal when doing a comparison?


Solution

  • it's not pretty but this works with me

    it "assigns all rate_card_details as @rate_card_details" do
      rate_card_detail = FactoryGirl.create(:rate_card_detail)
      get :index, {}, valid_session
      assigns(:rate_card_details).first.attributes.values.each_with_index do |rcd,i|
        r_c_d = rate_card_detail[i]
        if rcd.is_a?BigDecimal
          rcd = rcd.to_s
          r_c_d = r_c_d.to_s
        end
        expect(rcd).to eq(r_c_d)
      end
    end