J'ai une classe et un comparateur pour cette classe qui implémente IEqualityComparer
:Comment implémenter des tests unitaires sur IEqualityComparer?
class Foo
{
public int Int { get; set; }
public string Str { get; set; }
public Foo(int i, string s)
{
Int = i;
Str = s;
}
private sealed class FooEqualityComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
if (x.GetType() != y.GetType()) return false;
return x.Int == y.Int && string.Equals(x.Str, y.Str);
}
public int GetHashCode(Foo obj)
{
unchecked
{
return (obj.Int * 397)^(obj.Str != null ? obj.Str.GetHashCode() : 0);
}
}
}
public static IEqualityComparer<Foo> Comparer { get; } = new FooEqualityComparer();
}
Les deux méthodes Equals
et GetHashCode
sont utilisés par exemple dans List.Except
par une instance du comparateur.
Ma question est: comment implémenter correctement les tests unitaires sur ce comparateur? Je veux détecter si quelqu'un ajoute une propriété publique dans Foo
sans modifier le comparateur, car dans ce cas le comparateur devient invalide.
Si je fais quelque chose comme:
Assert.That(new Foo(42, "answer"), Is.EqualTo(new Foo(42, "answer")));
Cela ne peut pas détecter qu'une nouvelle propriété a été ajoutée, et que cette propriété est différente dans les deux objets.
Y at-il un moyen de le faire?
Si c'est possible, pouvons-nous ajouter un attribut à une propriété pour dire que cette propriété n'est pas pertinente dans la comparaison?
Vous ne pouvez pas attendre votre comparateur pour comparer les propriétés, il ne sait pas qu'ils existent. Vous devez changer le comparateur pour vérifier également les nouvelles propriétés. Vous pourriez y parvenir en utilisant la réflexion mais cela rendrait votre comparateur incroyablement lent. – HimBromBeere
'Foo' devrait être immuable si vous avez l'intention de l'utiliser comme clé dans les tables de hachage. Dans ce cas, les nouvelles propriétés doivent être définies en utilisant les paramètres du ctor, et tout le monde verrait que votre test pour le Comparer ne se compile plus. (Et j'espère mettre à jour le comparateur et le test). Un autre moyen facile, ajoutez simplement un commentaire dans Foo pour que Comparer XXX ait besoin d'être mis à jour. – Magnus
@Magnus Cela semble intéressant, mais comment faire cela? – Boiethios