Dart Matcher Bonnes Pratiques
Quand utiliser cette skill
Utilisez cette skill quand :
- Vous écrivez des assertions avec
expectetpackage:matcher. - Vous migrez des vérifications manuelles héritées vers des matchers plus propres.
- Vous debuggez des échecs de test déroutants.
Découverte
Pour trouver des candidates à l'amélioration de l'utilisation des matchers, recherchez des motifs sous-optimaux :
Vérifications de Longueur Sous-Optimales
Recherchez les vérifications de longueur qui devraient utiliser hasLength :
- Regex :
expect\([^,]+.length,\s*
Vérifications Booléennes Sous-Optimales
Recherchez les vérifications sur des propriétés booléennes qui ont des matchers spécifiques :
- Regex :
expect\([^,]+.isEmpty,\s*(true|equals\(true\)) - Regex :
expect\([^,]+.isNotEmpty,\s*(true|equals\(true\)) - Regex :
expect\([^,]+.contains\(.*\),\s*(true|equals\(true\))
Recherches de Map Sous-Optimales
Recherchez les recherches manuelles dans des maps au lieu d'utiliser containsPair :
- Regex :
expect\([^,]+\[.*\],\s*
Matchers Principaux
1. Collections (hasLength, contains, isEmpty, unorderedEquals, containsPair)
-
hasLength(n):- Préférez
expect(list, hasLength(n))àexpect(list.length, n). - Donne de meilleurs messages d'erreur en cas d'échec (affiche le contenu réel de la liste).
- Préférez
-
isEmpty/isNotEmpty:- Préférez
expect(list, isEmpty)àexpect(list.isEmpty, true). - Préférez
expect(list, isNotEmpty)àexpect(list.isNotEmpty, true).
- Préférez
-
contains(item):- Vérifiez l'existence sans itération manuelle.
- Préférez à
expect(list.contains(item), true).
-
unorderedEquals(items):- Vérifiez le contenu indépendamment de l'ordre.
- Préférez à
expect(list, containsAll(items)).
-
containsPair(key, value):- Vérifiez qu'une map contient une paire clé-valeur spécifique.
- Préférez à vérifier
expect(map[key], value)ouexpect(map.containsKey(key), true).
2. Vérifications de Type (isA<T> et TypeMatcher<T>)
-
isA<T>():- Préférez pour les assertions en ligne :
expect(obj, isA<Type>()). - Plus concis et lisible que
TypeMatcher<Type>(). - Permet de chaîner des contraintes avec
.having().
- Préférez pour les assertions en ligne :
-
TypeMatcher<T>:- Préférez quand vous définissez des matchers réutilisables au niveau du fichier.
- Utilisez
const:const isMyType = TypeMatcher<MyType>(); - Le chaînage
.having()fonctionne aussi ici, mais le matcher résultant n'est pasconst.
3. Propriétés d'Objet (having)
Utilisez .having() sur isA<T>() ou d'autres TypeMatchers pour vérifier les propriétés.
- Noms Descriptifs : Utilisez des noms de paramètres significatifs dans la closure (p. ex.,
(e) => e.message) au lieu de noms génériques commep0pour améliorer la lisibilité.
expect(person, isA<Person>()
.having((p) => p.name, 'name', 'Alice')
.having((p) => p.age, 'age', greaterThan(18)));
Cela fournit des messages d'échec détaillés indiquant exactement quelle propriété a échoué.
4. Assertions Asynchrones
-
completion(matcher):- Attendez qu'une future se termine et vérifiez sa valeur.
- Préférez
await expectLater(...)pour s'assurer que la future se termine avant que le test ne continue. await expectLater(future, completion(equals(42))).
-
throwsA(matcher):- Vérifiez qu'une future ou une fonction lance une exception.
await expectLater(future, throwsA(isA<StateError>())).expect(() => function(), throwsA(isA<ArgumentError>()))(une fonction synchrone qui lance est correcte avecexpect).
5. Utilisation de expectLater
Utilisez await expectLater(...) quand vous testez un comportement asynchrone pour assurer un séquençage correct.
// BON : Attend que la future se termine avant de vérifier les effets de bord
await expectLater(future, completion(equals(42)));
expect(sideEffectState, equals('done'));
// MAUVAIS : La vérification de l'effet de bord peut s'exécuter avant que la future se termine
expect(future, completion(equals(42)));
expect(sideEffectState, equals('done')); // Condition de course !
Principes
- Échecs Lisibles : Choisissez des matchers qui produisent des messages d'erreur clairs.
- Évitez la Logique Manuelle : N'utilisez pas d'instructions
ifou de bouclesforpour les assertions ; laissez les matchers s'en charger. - Matchers Spécifiques : Utilisez le matcher le plus spécifique disponible (p. ex.,
containsPairpour les maps au lieu de vérifier les clés manuellement).
Skills Connexes
- dart-test-fundamentals : Concepts principaux pour structurer les tests, les cycles de vie et la configuration.
- dart-checks-migration : Utilisez cette
skill si vous migrez des tests de
package:matchervers le modernepackage:checks.