Technique permettant de vérifier automatiquement la cohérence d’égaux, de hashCode et de compareTo?

Je suis bien conscient des besoins contractuels pour s’assurer que hashCode est cohérent avec les equals et qu’il est cohérent avec compareTo . Cependant, cela est souvent violé dans la pratique . Existe-t-il des outils, techniques ou bibliothèques capables de tester automatiquement cette cohérence?

Je soupçonne malheureusement que la réponse est «non», mais il serait utile de pouvoir effectuer un test unitaire pour ce type de tâche, qui pourrait utiliser un appel à une bibliothèque ou un framework plutôt que de devoir écrire manuellement un test personnalisé. chaque cas où il est important.

Au cas où ce que je veux dire par cohérence ne soit pas clair, pour hashCode et equals je fais référence à ce qui suit:

Si deux objects sont égaux selon la méthode equals (Object), alors l’appel de la méthode hashCode sur chacun des deux objects doit produire le même résultat entier.

Pour equals et compareTo je me réfère à ce qui suit:

L’ordre naturel pour une classe C est dit cohérent avec equals si et seulement si e1.compareTo (e2) == 0 a la même valeur booléenne que e1.equals (e2) pour chaque e1 et e2 de la classe C.

    Les tests de Guava ont un utilitaire appelé EqualsTester que nous utilisons au quotidien dans nos tests unitaires pour tester les equals et le hashCode . Son utilisation ressemble à

     new EqualsTester() .addEqualityGroup("hello", "h" + "ello") .addEqualityGroup("world", "wor" + "ld") .addEqualityGroup(2, 1 + 1) .testEquals(); 

    qui teste que toutes les valeurs du même groupe sont égales et ont les mêmes codes de hachage, que différents groupes ne sont pas égaux et que divers autres invariants sont tous satisfaits. Vous pouvez soit l’utiliser vous-même, soit simplement emprunter ses idées.

    Je serais extrêmement surpris qu’il soit possible de tester sans générer ou spécifier explicitement des valeurs de test, simplement parce que cela semble très probablement équivalent au problème d’arrêt.

    Si vous utilisez JUnit, le package d’extensions contient EqualsHashCodeTestCase , qui teste intégralement equals et hashCode pour tout ce qui est décrit dans la spécification Java (réflexive, transitive, symésortingque, etc.). Tout ce que vous avez à faire est de fournir un object égal et non égal à la classe parente à utiliser pour la vérification.

    Comme la méthode CompareTo fait partie de l’interface Comparable, elle est en fait divisée en un autre scénario de test – ComparabilityTestCase . Cela prend trois objects – un de valeur inférieure, une valeur égale et une valeur supérieure. Remplacez-les et la classe parent s’occupera du rest.

    J’ai écrit quelques méthodes utilitaires pour aider le test unitaire des méthodes hashCode et equals:

    http://softsmithy.sourceforge.net/devlib/docs/api/org/softsmithy/devlib/junit/Tests.html

    La bibliothèque est Open Source et peut être téléchargée ici: http://sourceforge.net/projects/softsmithy/files/softsmithy-devlib/v0.1/

    ou avec Maven:

       org.softsmithy.devlib devlib-core 0.1 test  

    Il existe un outil très intéressant appelé Korat qui peut effectuer des recherches exhaustives pour vérifier l’exactitude des classes Java pour les petits cas. En fait, il examine le code exécuté afin de générer tous les différents cas de test d’une taille donnée pouvant être distingués par le programme. Je ne sais pas à quel point c’est utile dans les cas importants, mais pour de nombreux programmes, il peut être utilisé pour vérifier automatiquement si de tels cas fonctionnent correctement.

    J’espère que cela t’aides!

    J’ai récemment utilisé meanbean (http://meanbean.sourceforge.net/) pour tester automatiquement une classe pour les contrats equals () et hashCode () (ainsi que les paires setter / getter).

    “Haricot moyen:

    1. Vérifie que les paires de méthodes getter et setter d’un JavaBean / POJO fonctionnent correctement.

    2. Vérifie que les méthodes equals et hashCode d’une classe sont respectivement conformes aux contrats Equals et HashCode Contract.

    3. Vérifie l’importance de la propriété en égalité d’object. ”

    Il me rest encore beaucoup de questions spécifiques à meanbean: vérifie-t-il la cohérence de equals () et de hashCode ()? De plus, je n’ai pas essayé de le vaincre. Je crois qu’il n’a aucun support pour compareTo (). Et je n’ai pas essayé d’autres alternatives. Intéressé par l’expérience des autres.