Rspec - 检查数组是否具有与其他元素相同的元素,无论顺序如何

pie*_*ard 7 ruby rspec ruby-on-rails ruby-on-rails-2

我不确定它是否是一个Rspec问题,但我只是在Rspec测试中加入了这个问题.

我想检查数组是否等于另一个数组,无论元素顺序如何:

[:b, :a, :c] =?= [:a, :b, :c]
Run Code Online (Sandbox Code Playgroud)

我目前的版本:

my_array.length.should == 3
my_array.should include(:a)
my_array.should include(:b)
my_array.should include(:c)
Run Code Online (Sandbox Code Playgroud)

在Rspec,ruby或Rails上是否有任何方法可以执行以下操作:

my_array.should have_same_elements_than([:a, :b, :c])
Run Code Online (Sandbox Code Playgroud)

问候

And*_*ite 33

match_arrayRSpec中有一个匹配器可以做到这一点:

http://rubydoc.info/github/rspec/rspec-expectations/RSpec/Matchers:match_array


Ste*_*fan 12

您可以使用=~运营商:

[:b, :a, :c].should =~ [:a, :b, :c] # pass
Run Code Online (Sandbox Code Playgroud)

来自文档:

如果实际包含所有预期而不管订单,则通过.这适用于集合.传递多个args,只有在集合中找到所有args时才会通过.

对于RSpec的期望语法,有match_array:

expect([:b, :a, :c]).to match_array([:a, :b, :c]) # pass
Run Code Online (Sandbox Code Playgroud)

或者contain_exactly如果你传递单个元素:

expect([:b, :a, :c]).to contain_exactly(:a, :b, :c) # pass
Run Code Online (Sandbox Code Playgroud)


apn*_*ing 2

错误的匹配器(感谢@steenslag):

RSpec::Matchers.define :be_same_array_as do |expected_array|
  match do |actual_array|
    (actual_array | expected_array) - (actual_array & expected_array) == []
  end
end
Run Code Online (Sandbox Code Playgroud)

其他解决方案:

  • 使用内置匹配器,最佳解决方案

  • 使用Set

就像是:

require 'set'
RSpec::Matchers.define :be_same_array_as do |expected_array|
  match do |actual_array|
    Set.new(actual_array) == Set.new(expected_array)
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 没有必要经历这一切。只需使用内置运算符“=~”,就像 Stefan 的回答一样。 (2认同)