Rspec:“array.should == another_array”但不关心顺序
Posted
技术标签:
【中文标题】Rspec:“array.should == another_array”但不关心顺序【英文标题】:Rspec: "array.should == another_array" but without concern for order 【发布时间】:2011-02-28 01:35:10 【问题描述】:我经常想比较数组并确保它们以任意顺序包含相同的元素。在 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
当数组元素没有实现#<=>
时,这会失败
【问题讨论】:
不是聪明人,而是比较to_set
和 size
实际上并没有达到你想要的效果。例如。 [a, b, b] 将匹配 [a, a, b]。干杯!
对于那些偶然发现相反情况的人:顺序应该相同。使用 eq
匹配器,例如expect([1, 2]).to_not eq([2, 1])
【参考方案1】:
试试array.should =~ another_array
我能找到的最好的文档是代码本身,即here。
【讨论】:
这不考虑订单,所以这不是一个可以接受的答案,是吗?引用自docs:Passes 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])
参见:***.com/a/19436763/33226【参考方案2】:
从 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_array
是 contain_exactly
(documentation) 的别名【参考方案3】:
我发现=~
是不可预测的,并且它没有明显的原因失败了。过去 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/…【参考方案4】:
没有很好地记录,但我还是添加了链接:
Rspec3 docs
expect(actual).to eq(expected)
Rspec2 docs
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
。【参考方案5】:
对于 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
【讨论】:
【参考方案6】:使用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
【讨论】:
以上是关于Rspec:“array.should == another_array”但不关心顺序的主要内容,如果未能解决你的问题,请参考以下文章
ruby [rspec]“使用RSpec测试Rails程序”笔记
RSpec vs Cucumber(RSpec 故事)[关闭]
失败/错误:需要'rspec/rails'类型错误:错误的参数类型类(预期模块)Rspec V3
rails-rspec 错误无法加载此类文件 -- rspec/core/formatters/progress_formatter