Rspec: "array.should == another_array", но без заботы о заказе
Я часто хочу сравнить массивы и убедиться, что они содержат одинаковые элементы в любом порядке. Есть ли краткий способ сделать это в 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
Это терпит неудачу, когда элементы массива не реализуют #<=>
Ответы
Ответ 1
Используйте match_array
, который принимает другой массив в качестве аргумента, или contain_exactly
, который принимает каждый элемент в качестве отдельного аргумента и иногда полезен для удобства чтения. (документы)
Примеры:
expect([1, 2, 3]).to match_array [3, 2, 1]
или же
expect([1, 2, 3]).to contain_exactly 3, 2, 1
Ответ 2
Попробуйте array.should =~ another_array
Лучшая документация, которую я могу найти, это сам код, который здесь.
Ответ 3
Так как 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])
Ответ 4
Я обнаружил, что =~
непредсказуем, и он потерпел неудачу без видимых причин. В прошлом 2.14 вы должны, вероятно, использовать
expect([1, 2, 3]).to match_array([2, 3, 1])
Ответ 5
Для 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 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
не задокументировано очень хорошо, но я добавил ссылки в любом случае:
expect(actual).to eq(expected)
expect([1, 2, 3]).to match_array([2, 3, 1])