279 votes

Rspec : "array.should == another_array" mais sans se soucier de l'ordre

Je souhaite souvent comparer des tableaux et m'assurer qu'ils contiennent les mêmes éléments, dans n'importe quel ordre. Existe-t-il un moyen concis de le faire dans RSpec ?

Voici des méthodes qui ne sont pas acceptables :

#to_set

Par exemple :

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

ou

array.to_set.should == another_array.to_set

Cela échoue lorsque les tableaux contiennent des éléments en double.

#sort

Par exemple :

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

ou

array.sort.should == another_array.sort

Cela échoue lorsque les éléments du tableau n'implémentent pas l'option #<=>

7 votes

Je ne veux pas faire le malin, mais en comparant to_set y size ne fait pas ce que vous voulez. Par exemple, [a, b, b] correspondrait à [a, a, b]. À la vôtre !

4 votes

Pour ceux qui sont tombés ici en se demandant le contraire : l'ordre devrait être le même . Utilisez le eq matcher, par exemple expect([1, 2]).to_not eq([2, 1])

274voto

x1a4 Points 14082

Essayez array.should =~ another_array

La meilleure documentation que je puisse trouver à ce sujet est le code lui-même, qui est le suivant aquí .

0 votes

Cela ne tient pas compte de l'ordre, donc ce n'est pas une réponse acceptable, n'est-ce pas ? Citation du docs : Passes if actual contains all of the expected regardless of order. .

23 votes

Titre de ce poste : "Rspec : "array.should == another_array" mais sans se préoccuper de l'ordre".

4 votes

Ceci est maintenant officiellement documenté sous opérateurs de jumelage

273voto

Valentin Nemcev Points 2186

Depuis RSpec 2.11, vous pouvez également utiliser l'option match_array .

array.should match_array(another_array)

Ce qui pourrait être plus lisible dans certains cas.

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

8 votes

Oui, je viens de passer à rails 4 et =~ ne fonctionne plus alors que match_array fonctionne bien, merci !

2 votes

Je ne sais pas si c'est plus lisible. Maintenant, on dirait que ça devrait être une correspondance exacte, mais ça ne l'est pas. Le gribouillis précédent était suffisamment vague pour ne rien signifier pour un tableau, donc je n'avais pas cette idée préconçue. Peut-être que c'est juste moi.

1 votes

Pour "exact", vous avez toujours eq() donc je suppose match_array() est assez vague pour moi.

147voto

Josh Kovach Points 2759

J'ai trouvé =~ pour être imprévisible et il est tombé en panne sans raison apparente. Après la 2.14, vous devriez probablement utiliser

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

18 votes

Également valable après la version 3.0 : expect([1, 2, 3]).to contain_exactly(2, 3, 1) . relishapp.com/rspec/rspec-expectations/v/3-0/docs/

50voto

nicholaides Points 7859

Utilisez match_array qui prend un autre tableau comme argument, ou bien contain_exactly qui prend chaque élément comme un argument séparé, et qui est parfois utile pour la lisibilité. ( docs )

Exemples :

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

ou

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

17voto

Tim Diggins Points 1578

Pour RSpec 3, utilisez contain_exactly :

Voir https://relishapp.com/rspec/rspec-expectations/v/3-2/docs/built-in-matchers/contain-exactly-matcher pour les détails, mais voici un extrait :

Le matcheur contain_exactly permet de tester les tableaux les uns par rapport aux autres d'une manière qui permet d'éviter les erreurs. qui ne tient pas compte des différences dans l'ordre entre le tableau réel et le tableau attendu. Par exemple :

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

Comme d'autres l'ont souligné, si vous voulez affirmer le contraire, c'est-à-dire que les tableaux doivent correspondre à la fois au contenu et à l'ordre, utilisez alors eq , ie. :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X