assert_equal говорит, что <0,15> ожидается, но было <0,15>, но только если метод вычисляет 0,15 определенным образом - PullRequest
4 голосов
/ 16 августа 2010

Так что для этой модели метод:

def tax_rate
  tax_rate = 0.0
  tax_rate += STATE_TAX if state_taxable?  #STATE_TAX = 0.1
  tax_rate += IMPORT_TAX if imported?      #IMPORT_TAX = 0.05
  tax_rate
end

Этот тест не пройден:

@item.update_attributes({:state_taxable => true,
                         :imported => true,
                         :price => 32.19})
assert_equal 0.15, @item.tax_rate

Я получаю эту ошибку:

<0.15> expected but was <0.15>.

Однако, этот тест пройдет:

@item.update_attributes({:state_taxable => true,
                         :imported => false,
                         :price => 14.99})
assert_equal 0.1, @item.tax_rate

Таким образом, я получаю ошибку, когда tax_rate равен 0,0 + 0,1 + 0,05, но не когда он равен 0,0 + 0,1 или 0,0 + 0,05. Обе 0,15 - это числа с плавающей точкой, поэтому я не вижу, что может быть причиной этого. Я слишком долго размышлял над этим, надеюсь, кто-то может указать, кто виноват. Заранее спасибо, ребята.

Ответы [ 4 ]

9 голосов
/ 16 августа 2010

Числа с плавающей точкой не могут быть представлены точно; вам нужно использовать assert_in_delta, чтобы проверить, что вы находитесь в указанном диапазоне.

Что-то вроде assert_in_delta 0.15, @item.tax_rate, 0.001 должно сделать это: оно проверит, что вы находитесь в пределах 0,001 от ожидаемого значения.

3 голосов
/ 16 августа 2010

ИМХО, вам следует хранить такие вещи, как целые числа (в центах).

1 голос
/ 16 августа 2010

Я неоднократно сталкивался с этой ошибкой, потому что это были разные классы .

Попробуйте

assert_equal 0.15.class, @item.tax_rate.class

И я уверен, что это скажет что-то вроде

<float> expected but was <double>.

Если вы сделаете

assert_equal 0.15.to_float, @item.tax_rate.to_float

Это, вероятно, пройдет

0 голосов
/ 16 августа 2010

0.1, наряду с другими числами, не может быть точно представлено в арифметике с плавающей точкой.Следовательно, вы должны использовать что-то вроде (я не Ruby парень):

assert_true abs(0.15 - @item.tax_rate) < 0.0001

И вообще, вы не должны использовать поплавки для денег / валюты: есть много действительно неприятных тонкихвопросы, которые будут терять деньги между трещинами.См этот вопрос .

...