Rspec:“数组。Should == another_array"但不关心秩序

我经常希望比较数组,并确保它们以任何顺序包含相同的元素。在RSpec中是否有一种简洁的方法来做到这一点?

以下是一些不可接受的方法:

#to_set

例如:

expect(array.to_set).to eq another_array.to_set

array.to_set.should == another_array.to_set

当数组包含重复项时,此操作将失败。

#sort

例如:

expect(array.sort).to eq another_array.sort

array.sort.should == another_array.sort

当数组元素没有实现#<=>时,此方法将失败

81511 次浏览

尝试array.should =~ another_array

关于这一点,我能找到的最好的文档是代码本身,即在这里

从RSpec 2.11开始,你也可以使用match_array

array.should match_array(another_array)

这在某些情况下可读性更好。

[1, 2, 3].should =~ [2, 3, 1]
# vs
[1, 2, 3].should match_array([2, 3, 1])

我发现=~是不可预测的,它失败了,没有明显的原因。超过2.14,你可能应该使用

expect([1, 2, 3]).to match_array([2, 3, 1])

没有很好地记录,但我添加了链接:

Rspec3 文档

expect(actual).to eq(expected)


Rspec2 文档

expect([1, 2, 3]).to match_array([2, 3, 1])

对于RSpec 3,使用contain_exactly:

详细信息请参见https://relishapp.com/rspec/rspec-expectations/v/3-2/docs/built-in-matchers/contain-exactly-matcher,但这里有一个摘录:

contain_exactly匹配器提供了一种方法来测试数组之间是否存在差异 这忽略了实际数组和期望数组之间的顺序差异。 例如:< / p >

    expect([1, 2, 3]).to    contain_exactly(2, 3, 1) # pass
expect([:a, :c, :b]).to contain_exactly(:a, :c ) # fail

正如其他人指出的那样,如果你想断言相反的情况,即数组应该同时匹配内容和顺序,那么使用eq,即:

    expect([1, 2, 3]).to    eq([1, 2, 3]) # pass
expect([1, 2, 3]).to    eq([2, 3, 1]) # fail

使用match_array,它接受另一个数组作为参数,或contain_exactly,它接受每个元素作为单独的参数,有时对可读性很有用。(文档)

例子:

expect([1, 2, 3]).to match_array [3, 2, 1]

expect([1, 2, 3]).to contain_exactly 3, 2, 1