Comment faire Valoir.AreEqual déterminer l'égalité entre les deux génériques IEnumerables?
J'ai une unité de test pour vérifier si une méthode retourne le bon IEnumerable
. La méthode s'appuie l'énumérable à l'aide de yield return
. La classe qu'il est une énumération de est ci-dessous:
enum TokenType
{
NUMBER,
COMMAND,
ARITHMETIC,
}
internal class Token
{
public TokenType type { get; set; }
public string text { get; set; }
public static bool operator == (Token lh, Token rh) { return (lh.type == rh.type) && (lh.text == rh.text); }
public static bool operator != (Token lh, Token rh) { return !(lh == rh); }
public override int GetHashCode()
{
return text.GetHashCode() % type.GetHashCode();
}
public override bool Equals(object obj)
{
return this == (Token)obj;
}
}
C'est la partie pertinente de la méthode:
foreach (var lookup in REGEX_MAPPING)
{
if (lookup.re.IsMatch(s))
{
yield return new Token { type = lookup.type, text = s };
break;
}
}
Si je stocker le résultat de cette méthode dans actual
, faire un autre énumérable expected
, et de les comparer comme ça...
Assert.AreEqual(expected, actual);
..., l'assertion échoue.
J'ai écrit une méthode d'extension pour IEnumerable
qui est similaire à Python zip
function (il combine deux IEnumerables dans un ensemble de paires) et essayé ceci:
foreach(Token[] t in expected.zip(actual))
{
Assert.AreEqual(t[0], t[1]);
}
Il a travaillé! Quelle est donc la différence entre ces deux Assert.AreEqual
s?
- Baker: merci de ne pas mal le prendre, avez-vous considéré que le fait d'avoir poser une question comme celle-ci, pourrait signifier que vous faire des choses trop compliquées?
- Hum... non, pas vraiment. 🙂 Pourriez-vous m'indiquer vers où je suis en train de faire des choses compliquées?
- Aussi, je ne suis pas convaincu que l'utilisation de texte".GetHashCode() % type.GetHashCode();" comme une valeur de retour pour GetHashCode() est une bonne idée...
- Blé - je ne suis pas sûr non plus... mais c'est le sujet d'une autre question.
Vous devez vous connecter pour publier un commentaire.
Assert.AreEqual
va comparer les deux objets à portée de main.IEnumerable
s sont des types dans et d'eux-mêmes, et de fournir un mécanisme pour effectuer une itération sur certains de la collection...mais ils ne sont pas réellement cette collection. L'original de votre comparaison par rapport à deuxIEnumerable
s, ce qui est une bonne base de comparaison...mais pas ce dont vous avez besoin. Vous avez besoin de comparer ce que les deuxIEnumerable
s étaient destinés à énumérer.Ici est de savoir comment je compare deux enumerables:
Je ne suis pas sûr de savoir si le ci-dessus est à moins de code que votre
.Zip
méthode, mais c'est à peu près aussi simple que cela.Trouvé:
Avez-vous considéré l'utilisation de la
CollectionAssert
classe à la place...considérant qu'il est destiné à effectuer des vérifications d'égalité sur les collections?Addendum:
Si les "collections" comparés sont des énumérations, puis il suffit de les envelopper avec '
new List<T>(enumeration)
' est le moyen le plus facile pour effectuer la comparaison. La construction d'une nouvelle liste provoque une surcharge, bien sûr, mais dans le contexte d'un test unitaire, cela ne devrait pas trop j'espère?new List<T>(enumeration)
afin que je puisse effectuer la comparaison. C'est pas comme si la surcharge est susceptible d'être un problème dans le cadre d'un test unitaire.Je pense que le plus simple et le plus clairement possible d'affirmer l'égalité que vous voulez est une combinaison de la réponse par jerryjvl et des commentaires sur son post par MEMark - combiner
CollectionAssert.AreEqual
avec les méthodes d'extension:Cela donne des informations plus complètes que les SequenceEqual réponse suggérée par les OP (il vous dira à quel élément a été trouvé que c'était inattendu). Par exemple:
Vous serez vraiment heureux vous avez fait de cette façon si votre test échoue - parfois, vous pouvez même savoir quel est le problème sans avoir à sortir le débogueur - et hey, vous êtes en train de faire TDD droit, de sorte que vous écrivez un test en échec en premier, d'accord? 😉
Les messages d'erreur d'obtenir encore plus utile si vous utilisez
AreEquivalent
pour tester l'équivalence (l'ordre n'a pas d'importance):