wake-up-neo.com

Rspec: "array.should == another_array", aber ohne Sorge um die Reihenfolge

Ich möchte häufig Arrays vergleichen und sicherstellen, dass sie in jeder beliebigen Reihenfolge die gleichen Elemente enthalten. Gibt es eine kurze Möglichkeit, dies in RSpec zu tun?

Hier sind Methoden, die nicht akzeptabel sind:

#to_set

Zum Beispiel:

expect(array.to_set).to eq another_array.to_set

oder

array.to_set.should == another_array.to_set

Dies schlägt fehl, wenn die Arrays doppelte Elemente enthalten.

#sort

Zum Beispiel:

expect(array.sort).to eq another_array.sort

oder

array.sort.should == another_array.sort

Dies schlägt fehl, wenn die Arrayelemente #<=> nicht implementieren.

218
nicholaides

Verwenden Sie match_array, das ein anderes Array als Argument verwendet, oder contain_exactly, wobei jedes Element als separates Argument verwendet wird. Dies ist manchmal für die Lesbarkeit hilfreich. ( docs )

Beispiele:

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

oder

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

array.should =~ another_array ausprobieren

Die beste Dokumentation dazu ist der Code selbst, der hier ist.

260
x1a4

Seit RSpec 2.11 können Sie auch match_array verwenden.

array.should match_array(another_array)

Welches könnte in einigen Fällen lesbarer sein.

[1, 2, 3].should =~ [2, 3, 1]
# vs
[1, 2, 3].should match_array([2, 3, 1])
221
Valentin Nemcev

Ich habe festgestellt, dass =~ unvorhersehbar ist, und es ist ohne ersichtlichen Grund fehlgeschlagen. Nach 2.14 sollten Sie wahrscheinlich verwenden

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

Für RSpec 3 verwenden Sie contain_exactly:

Siehe https://relishapp.com/rspec/rspec-expectations/v/3-2/docs/built-in-matchers/contain-exactly-matcher für Details, aber hier ist ein Auszug:

Mit dem match_exactly-Matcher können Arrays auf eine Art und Weise gegeneinander getestet werden Dabei werden Unterschiede in der Reihenfolge zwischen dem tatsächlichen und dem erwarteten Array nicht berücksichtigt. Zum Beispiel:

    expect([1, 2, 3]).to    contain_exactly(2, 3, 1) # pass
    expect([:a, :c, :b]).to contain_exactly(:a, :c ) # fail

Wie andere darauf hingewiesen haben, wenn Sie das Gegenteil behaupten möchten, dass die Arrays sowohl Inhalt als auch Reihenfolge entsprechen sollten, verwenden Sie eq, dh:

    expect([1, 2, 3]).to    eq(1, 2, 3) # pass
    expect([1, 2, 3]).to    eq(2, 3, 1) # fail
0
Tim Diggins

nicht sehr gut dokumentiert, aber ich habe trotzdem Links hinzugefügt:

Rspec3 docs

expect(actual).to eq(expected)


Rspec2 docs

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

0
Blair Anderson