Rspec:“ array.should == another_array”,但无需担心顺序


235

我经常想比较数组,并确保它们以任何顺序包含相同的元素。在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

当数组元素未实现时,此操作将失败 #<=>


7
不是对smartass,而是进行比较to_setsize实际上并没有做您想要的。例如[a,b,b]将匹配[a,a,b]。干杯!
Jo Liss

3
对于那些偶然发现这里相反的人:顺序应该相同。使用eq匹配器,例如expect([1, 2]).to_not eq([2, 1])
Dennis

Answers:


263

尝试 array.should =~ another_array

我能找到的最好的文档是代码本身,在这里


这没有考虑订单,因此这不是可接受的答案,对吗?从报价文档Passes if actual contains all of the expected regardless of order.
Joshua Muheim 2013年

16
这篇文章的标题:“ Rspec:“ array.should == another_array”,但无需担心顺序”
x1a4

3
现在已正式记录在操作员匹配器中
Kelvin

7
如果您使用的是rspec 3.0中新的“期望”语法,请参阅@JoshKovach的答案。
clozach 2014年

46
expect([1, 2, 3]).to match_array([2, 1, 3])请参见Rspec 3.0语法:stackoverflow.com/a/19436763/33226
Gavin Miller

238

从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])

8
是的,刚刚升级到Rails 4,=〜在match_array工作正常的地方停止了工作,谢谢!
opsb 2013年

2
我不知道这是否更具可读性。现在,它看起来像是完全匹配,但事实并非如此。先前的曲线模糊不清,对于数组来说毫无意义,所以我没有先入为主的观念。也许就是我。
Trejkaz 2014年

1
对于“精确”,您总是有eq(),所以我想match_array()对我来说还很模糊。
awendt 2014年

这对我在订购清单上不起作用。它认为具有相同项目(但顺序不同)的列表是相同的。:-(
djangofan

FWIW match_arraycontain_exactlydocumentation)的别名
Ruy Diaz


13

Use match_array,它将另一个数组作为参数,或contain_exactly,将每个元素作为单独的参数,有时对于提高可读性很有用。(docs

例子:

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

要么

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

3

对于RSpec 3,请使用contain_exactly

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

contain_exactly匹配器提供了一种以相互忽略的方式测试数组的方法,而无需考虑实际数组和预期数组之间的顺序差异。例如:

    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

1

没有很好的记录,但是我还是添加了链接:

Rspec3 文档

expect(actual).to eq(expected)


Rspec2 文档

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


11
期望(实际)。到eq(预期)和期望(实际)。到match_array(期望)在rspec3中都工作,但是他们在做不同的事情。#match_array忽略顺序,而#eq则不忽略。
古基

1
由于OP明确要求忽略该命令,因此无法回答问题。
没人的噩梦

是! 这对我有用。如果元素的顺序不同,则比较失败。谢谢!我指的是.to eq方法,而不是match_array
djangofan '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.