Rspec: „array.should == another_array”, ale bez obawy o porządek


235

Często chcę porównywać tablice i upewnić się, że zawierają te same elementy, w dowolnej kolejności. Czy istnieje zwięzły sposób na zrobienie tego w RSpec?

Oto metody, które są niedopuszczalne:

#to_set

Na przykład:

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

lub

array.to_set.should == another_array.to_set

Nie udaje się to, gdy tablice zawierają zduplikowane elementy.

#sort

Na przykład:

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

lub

array.sort.should == another_array.sort

Nie powiedzie się to, gdy elementy tablic nie zostaną zaimplementowane #<=>


7
Nie do smartassa, ale do porównywania to_seti sizefaktycznie nie robi tego, co chcesz. Np. [A, b, b] pasuje do [a, a, b]. Twoje zdrowie!
Jo Liss,

3
Dla tych, którzy natknęli się tutaj, zastanawiając się nad odwrotnością: porządek powinien być taki sam . Użyj eqdopasowywania, np.expect([1, 2]).to_not eq([2, 1])
Dennis

Odpowiedzi:


263

Próbować array.should =~ another_array

Najlepsza dokumentacja na ten temat, którą mogę znaleźć, to sam kod, który jest tutaj .


To nie uwzględnia kolejności, więc nie jest to akceptowalna odpowiedź, prawda? Cytat z docs : Passes if actual contains all of the expected regardless of order..
Joshua Muheim

16
Tytuł tego postu: „Rspec:„ array.should == another_array ”, ale bez obawy o zamówienie”
x1a4

3
Jest to teraz oficjalnie udokumentowane w ramach dopasowań operatorów
Kelvin,

7
Jeśli używasz nowej składni „expect” znalezionej w rspec 3.0, zapoznaj się z odpowiedzią @JoshKovach.
clozach

46
Składnia Rspec 3.0 jest dostępna expect([1, 2, 3]).to match_array([2, 1, 3]): stackoverflow.com/a/19436763/33226
Gavin Miller

238

Od wersji RSpec 2.11 możesz także używać match_array.

array.should match_array(another_array)

Co może być bardziej czytelne w niektórych przypadkach.

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

8
tak, właśnie uaktualniono do szyn 4 i = ~ przestał działać tam, gdzie match_array działa dobrze, dzięki!
opsb

2
Nie wiem, czy to jest bardziej czytelne. Teraz brzmi, jakby to miało być dokładne dopasowanie, ale tak nie jest. Poprzedni squiggle był na tyle niejasny, że nic nie znaczył dla tablicy, więc nie miałem wstępnego przekonania. Może to tylko ja.
Trejkaz

1
Jeśli chodzi o „dokładne”, zawsze masz eq(), więc myślę, że match_array()jest dla mnie wystarczająco niejasny.
awendt

To nie działa dla mnie na listach uporządkowanych. Uważa, że ​​listy, które mają te same elementy w innej kolejności, są takie same. :-(
djangofan

FWIW match_arrayto pseudonim contain_exactly( dokumentacja )
Ruy Diaz


13

Użyj match_array, która przyjmuje inną tablicę jako argument, lub contain_exactlyktóra bierze każdy element jako osobny argument i czasami jest przydatna dla czytelności. ( dokumenty )

Przykłady:

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

lub

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

3

W przypadku RSpec 3 użyj contain_exactly:

Zobacz https://relishapp.com/rspec/rspec-expectations/v/3-2/docs/built-in-matchers/contain-exactly-matcher, aby uzyskać szczegółowe informacje, ale oto fragment:

Match_exactly matcher zapewnia sposób testowania tablic względem siebie w sposób, który nie uwzględnia różnic w kolejności między rzeczywistą a oczekiwaną tablicą. Na przykład:

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

Jak zauważyli inni, jeśli chcesz twierdzić coś przeciwnego, że tablice powinny pasować zarówno do treści, jak i kolejności, użyj eq:

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

1

niezbyt dobrze udokumentowane, ale i tak dodałem linki:

Rspec3 docs

expect(actual).to eq(expected)


Rspec2 docs

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


11
Oba oczekują (rzeczywiste) .to eq (oczekiwane) i oczekują (rzeczywiste) .to match_array (oczekiwane) działają w rspec3, ale robią różne rzeczy. #match_array ignoruje kolejność, podczas gdy #eq nie.
gucki

1
To nie odpowiada na pytanie, ponieważ OP konkretnie poprosił o zignorowanie zamówienia.
NobodysNightmare

Tak! To zadziałało dla mnie. Porównanie kończy się niepowodzeniem, jeśli kolejność elementów nie jest taka sama. Dziękuję Ci! Mam na myśli .to eqmetodę, a nie match_array.
djangofan,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.