2011-01-18 21 views
15

给未来读者的提示:RSpec认为你的Hashes不等于?一个可能是一个OrderedHash,但是从常规的RSpec输出你不能说。这是促成这篇文章的问题。用于匹配Hashes的RSpec2匹配器是否存在?

原题:

假设我有一个规范,我想测试的方法生成相应的哈希值。

it 'should generate the Hash correctly' do 
    expected = {:foo => 1, 'baz' => 2} 
    subject.some_method_that_should_generate_the_hash.should == expected 
end 

这经常会失败,因为具有相同键值对的不同Hashes可能以不同的顺序返回它们的对。结果如下:

Failure/Error: subject.some_method_that_should_generate_the_hash.should == expected 
expected: {:foo => 1, 'baz' => 2}, 
    got: {'baz' => 2, :foo => 1} 

对于数组,这可以使用=〜运算符来解决。但是,这对于Hashes无效。现在,我已经使用

it 'should generate the Hash correctly' do 
    expected = {:foo => 1, 'baz' => 2} 
    subject.some_method_that_should_generate_the_hash.each {|k,v| 
    v.should == expected[k] 
    } 
end 

但这似乎不必要的冗长。我希望有一个明显的解决方案。我忽略文档中的某些内容还是RSpec没有适当的匹配哈希平等的匹配?

回答

17
describe 'Hash' do 
    let(:x) { { :a => 1, :b => 2 } } 
    let(:y) { { :b => 2, :a => 1 } } 

    it "should be equal with ==" do 
    x.should == y 
    end 
end 

通行证。我不确定你的具体情况是怎么回事。你可以分享一些失败的例子吗?

编程Ruby有这样一段话:

平等 - 两个散列相等,如果 它们具有相同的默认值,它们 包含相同的数字键,并 对应于每个键的值 第一个散列值等于(使用==)至 与 秒中相同的密钥值。

+0

昨天晚了,我发现了这个问题:我实际上并没有比较两个哈希:一个在一路上变成了OrderedHash。你不能从RSpec输出中看到这一点,我有点尴尬地说这不是我第一次陷入这个陷阱:/ – Confusion 2011-01-19 06:08:25

+3

有趣。因此,OrderedHash和Hash具有相同的键/值对并不相同 - 这很好理解。 – zetetic 2011-01-19 07:33:30

3

我相信eql?方法只检查两个散列具有相同的内容 所以IIRC在Rspec2你可以这样做:

expected = {:foo => 1, 'baz' => 2} 
    expected.should be_eql({'baz' => 2, :foo => 1}) 

而且测试应该通过

+0

或rspec的3,`希望(X)。为了EQL(Y )` – nruth 2016-04-27 16:18:47