比较RSpec中包含BigDecimal的哈希

Mik*_*mer 5 ruby hash rspec

我正在使用RSpec(3.x)来测试行为类似于计算器的对象。该对象将结果放入哈希中。但是我无法在测试中获得正确匹配的哈希值。这是我正在谈论的示例:

class ObjectUnderTest

  def calculate(a, b)
    value = a.to_d / b
    {
      value: value
    {
  end

end
Run Code Online (Sandbox Code Playgroud)

测试如下所示:

RSpec.describe ObjectUnderTest do

   it "calculates the product of two values" do
     o = ObjectUnderTest.new
     expect(o.calculate(1, 3)).to eql({value: 0.333})
   end
end
Run Code Online (Sandbox Code Playgroud)

问题在于0.333是浮点数,哈希中包含的实际值是BigDecimal。如果我在测试中更改了该行,则表示如下内容:

expect(o.calculate(1, 3)).to eql({value: 0.333.to_d(3)})
Run Code Online (Sandbox Code Playgroud)

...测试仍然失败A)因为精度不同,并且B)在我的实际代码中,我有几个键值对,并且我不想在所有代码上都调用k.to_d(some_precision)比较哈希以使其通过。

有没有一种方法可以使用a_value_之类的值与某个范围内的值进行比较,我不必在那里硬编码一个确切的数字吗?

Myr*_*ton 5

浮点数是不精确的(甚至到(0.1 + 0.2) == 0.3返回 false 的程度),因此您必须使用匹配器来允许值接近您的预期值而不是相等。RSpec be_within(x).of(y)(及其别名a_value_within(x).of(y))旨在匹配浮点数。RSpec 3 还支持可组合匹配器,match匹配器允许您通过将匹配器代替值来匹配嵌套的哈希/数组数据结构,因此您可以这样做:

expect(o.calculate(1, 3)).to match(value: a_value_within(0.001).of(0.333))
Run Code Online (Sandbox Code Playgroud)