it-roy-ru.com

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

Это терпит неудачу, когда элементы массива не реализуют #<=>

218
nicholaides

Используйте match_array, который принимает в качестве аргумента другой массив, или contain_exactly, который принимает каждый элемент в качестве отдельного аргумента и иногда полезен для удобства чтения. ( документы )

Примеры:

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

или же

expect([1, 2, 3]).to contain_exactly 3, 2, 1
6
nicholaides

Попробуйте array.should =~ another_array

Лучшая документация по этому вопросу, которую я могу найти, - это сам код, который находится здесь .

260
x1a4

Начиная с 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])
221
Valentin Nemcev

Я обнаружил, что =~ непредсказуем, и он потерпел неудачу без видимой причины. Прошлое 2.14, вы, вероятно, должны использовать

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

Для 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
0
Tim Diggins

не очень хорошо документировано, но я все равно добавил ссылки:

Rspec3 документы

expect(actual).to eq(expected)


Rspec2 документы

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

0
Blair Anderson