ChatGPT解决这个技术问题 Extra ChatGPT

Rspec:“array.should == another_array”但不关心顺序

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

以下是不可接受的方法:

#设置

例如:

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

或者

array.to_set.should == another_array.to_set

当数组包含重复项时,这会失败。

#种类

例如:

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

或者

array.sort.should == another_array.sort

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

不是聪明人,但比较 to_setsize 实际上并没有达到你想要的效果。例如 [a, b, b] 将匹配 [a, a, b]。干杯!
对于那些偶然发现相反情况的人:顺序应该相同。使用 eq 匹配器,例如 expect([1, 2]).to_not eq([2, 1])

x
x1a4

试试array.should =~ another_array

我能找到的最好的文档是代码本身,即 here


这不考虑订单,所以这不是一个可以接受的答案,是吗?引自 docsPasses if actual contains all of the expected regardless of order.
这篇文章的标题:“Rspec:“array.should == another_array”但不关心顺序”
现在正式记录在 operator matchers
如果您使用的是 rspec 3.0 中的新“expect”语法,请参阅@JoshKovach 的答案。
Rspec 3.0 语法为 expect([1, 2, 3]).to match_array([2, 1, 3]) 请参阅:stackoverflow.com/a/19436763/33226
V
Valentin Nemcev

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

是的,刚刚升级到 rails 4 并且 =~ 在 match_array 工作正常的地方停止工作,谢谢!
我不知道这是否更具可读性。现在它看起来应该是完全匹配的,但事实并非如此。之前的曲线模糊到对数组没有任何意义,所以我没有先入为主。也许这只是我。
对于“精确”,您总是有 eq(),所以我想 match_array() 对我来说已经足够模糊了。
这对我在有序列表中不起作用。它认为具有不同顺序的相同项目的列表是相同的。 :-(
FWIW match_arraycontain_exactly (documentation) 的别名
J
Josh Kovach

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

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

在 3.0 之后也有效:expect([1, 2, 3]).to contain_exactly(2, 3, 1)relishapp.com/rspec/rspec-expectations/v/3-0/docs/…
n
nicholaides

使用 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

n
notapatch

对于 RSpec 3,使用 contain_exactly

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

contains_exactly 匹配器提供了一种测试数组的方法,这种方法忽略了实际数组和预期数组之间的排序差异。例如:expect([1, 2, 3]).to contains_exactly(2, 3, 1) # 通过 expect([:a, :c, :b]).to contains_exactly(:a, :c ) # 失败

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

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

B
Blair Anderson

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

Rspec3 文档

expect(actual).to eq(expected)

Rspec2 文档

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


expect(actual).to eq(expected) 和 expect(actual).to match_array(expected) 都在 rspec3 中工作,但它们做的事情不同。 #match_array 忽略排序,而 #eq 不会。
这不能回答问题,因为 OP 明确要求忽略该命令。
是的!这对我有用。如果元素的顺序不同,则比较失败。谢谢!我指的是 .to eq 方法,而不是 match_array