我经常希望比较数组,并确保它们以任何顺序包含相同的元素。在RSpec中是否有一种简洁的方法来做到这一点?
以下是一些不可接受的方法:
# to_set
例如:
expect(array.to_set).to eq another_array.to_set
or
array.to_set.should == another_array.to_set
当数组包含重复项时,此操作将失败。
#排序
例如:
expect(array.sort).to eq another_array.sort
or
array.sort.should == another_array.sort
当数组元素没有实现#<=>时,将失败
使用match_array(它接受另一个数组作为参数)或contain_exactly(它接受每个元素作为单独的参数),有时有助于提高可读性。(文档)
例子:
expect([1, 2, 3]).to match_array [3, 2, 1]
or
expect([1, 2, 3]).to contain_exactly 3, 2, 1
从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])
对于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])。传递contain_exactly(2,3,1) #
Expect ([:a,:c,:b])。contain_exactly(:a,:c) #失败
正如其他人指出的那样,如果你想断言相反的情况,即数组应该同时匹配内容和顺序,那么使用eq,即:
expect([1, 2, 3]).to eq([1, 2, 3]) # pass
expect([1, 2, 3]).to eq([2, 3, 1]) # fail