17

未来读者请注意:认为 RSpec 不认为您的哈希值相等?一个可能是 OrderedHash,但从常规的 RSpec 输出中您无法分辨。这就是引发这篇文章的问题。

原始问题:

假设我有一个规范,我想测试一个方法是否生成了适当的哈希。

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

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

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

对于数组,这是使用 =~ 运算符解决的。但是,这不适用于哈希。目前,我已经求助于

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 没有适当的匹配器来实现无序哈希相等?

4

3 回答 3

19
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 编程有这样的说法:

相等——如果两个散列具有相同的默认值,它们包含相同数量的键,并且第一个散列中每个键对应的值等于(使用 ==)第二个散列中相同键的值,则它们是相等的.

于 2011-01-18T23:19:58.590 回答
7

自 8 个月以来,gemrspec-matchers支持匹配哈希:

expected.should be_hash_matching(subhash_or_equal)

有关更多详细信息,请参见此处:https ://github.com/rspec/rspec-expectations/pull/79

于 2012-07-07T18:30:24.800 回答
5

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

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

并且测试应该通过

于 2011-01-18T22:51:30.660 回答