| Propriété | Valeur |
|---|---|
| Catégorie | Usage (JustDummies.Usage) |
| Sévérité | 🟠 Avertissement |
| Activée par défaut | Non — opt-in |
Les générateurs sont des types référence : une position object, dynamic ou params object[] en accepte un sans aucune conversion. C’est le résidu que l’ADR-0006 ouvre un nouvel onglet ne pouvait pas fermer en supprimant les conversions implicites — il n’y avait rien à supprimer ici.
La recette survit alors sous forme d’objet opaque :
- un utilitaire d’assertion prenant
objectinspecte la recette —Assert.NotNull(Any.String())est vert pour toujours et n’assère rien ; - une ligne de théorie construite en
object[]livre le générateur lui-même au code sous test ; gen.Equals(value)se résout versobject.Equals, soit une égalité de référence contre un objet sans rapport : faux à chaque exécution et pour chaque graine.
Comment l’activer
dotnet_diagnostic.JD011.severity = warning
Non conforme
Assert.NotNull(Any.String().NonEmpty()); // JD011 : assère que la recette est non nulle. Elle l'est toujours.
object[] row = { Any.Int32().Positive(), 1 }; // JD011 : la ligne transporte une recette
bool same = Any.String().NonEmpty().Equals(expected); // JD011 : faux, toujours
Conforme
Assert.NotNull(Any.String().NonEmpty().Generate());
object[] row = { Any.Int32().Positive().Generate(), 1 };
bool same = Any.String().NonEmpty().Generate().Equals(expected);
Pourquoi elle est livrée en opt-in
L’ADR-0038 ouvre un nouvel onglet imposait que la valeur par défaut de cette règle soit tranchée sur mesure et non à l’intuition. Mise à l’épreuve sur les suites de ce dépôt, elle a produit aucun vrai positif et deux faux, tous deux dans un test de convention qui collecte délibérément des générateurs dans une List<object> — une forme indiscernable de l’erreur de ligne de théorie que la règle vise, donc impossible à exclure.
C’est une preuve faible en faveur d’une activation générale, et une bonne indication qu’elle a sa place dans la suite d’un consommateur, où les utilitaires d’assertion typés object sont courants et la réflexion sur des instances de générateurs ne l’est pas. Activez-la là.
Ce qui n’est pas signalé
- Une comparaison entre deux générateurs —
ReferenceEquals(original, narrowed)etfirst.Equals(second). Comparer des recettes par identité est la façon dont un test d’immuabilité prouve qu’une contrainte a retourné un nouveau générateur ;Generate()y détruirait la propriété sous test. Assert.Throws<T>(() => Any.String().WithLength(3)), qui se lie àFunc<object>et non àAction, produisant donc une véritable conversion générateur →object. Cette forme existe à plus de 88 endroits rien que dans ce dépôt.- Une valeur générée, ce qui est l’objectif.