web-dev-qa-db-fra.com

Dois-je tester l'unité hashCode/equals/toString?

Lors de l'écriture de classes Java, il n'est pas rare de générer des méthodes à l'aide de votre IDE tel que

  • toString()
  • equals()
  • hashCode()

Mais une fois que vous les avez générés à l'aide de l'EDI, ils font partie de votre base de code (dans SCM) et, par conséquent, tous les moyens de mesure de la qualité s'appliquent.

Surtout les méthodes equals et hashcode contiennent beaucoup de conditions. Si je n'écris pas de tests unitaires, le score de couverture de code (ligne, condition, mutation) est plutôt faible, en particulier si la classe à tester n'est pas très importante.

Certains outils de couverture prennent en charge le filtrage (c.-à-d. Cobertura), d'autres (c.-à-d. Jacoco) ne le font pas. Mais les outils de couverture ne révèlent qu'un symptôme - un code non testé - et, par conséquent, je ne demande pas s'il faut supprimer/ignorer le symptôme, mais comment traiter la cause fondamentale.

La question est: devrais-je écrire des tests unitaires pour ces méthodes?

  • Si oui, quelles sont les bonnes raisons de le faire? Et quelle est une approche raisonnable?
  • Si non, pourquoi pas?

Je ne demande pas les classes générées en général, comme les pojos JAXB, les WS-Clients, etc., qui peuvent être facilement générées automatiquement et exclues de l'analyse de couverture.

13
Gerald Mücke

Si vous générez ces méthodes, vous devriez probablement également générer les tests correspondants ;-)

Il peut être fastidieux de tester ces méthodes à la main, mais en fonction de ce que vous souhaitez garantir avec vos tests, il peut être intéressant de tester également ces méthodes. Contre-question: testeriez-vous les instructions de log? 

Cela dépend vraiment de ce que vous essayez d'accomplir. Certains diront: non, d'autres peuvent dire: fais.

Penser à certaines raisons pour ne pas tester de telles méthodes:

  • le code est généré et peut contenir beaucoup de champs. le tester peut conduire à de nombreuses combinaisons différentes qui seraient simplement fastidieuses à écrire/maintenir et peut-être que le générateur a déjà été testé suffisamment bon? ;-)
  • vous ne gagnez aucune valeur en mettant en œuvre des tests pour cela. Votre toString() ne sera utilisé que par les journaux ou par le débogueur, vous ne vous en souciez donc pas.
  • vous avez confiance que le code généré est suffisamment sûr pour hashcode et equals

Raisons pour tester de telles méthodes:

  • pour s'assurer que le résultat est comme prévu
  • vous voulez vous assurer que si vous régénérez ces méthodes, les utilisations précédentes de l'implémentation de méthode ne seront pas interrompues
  • vous utilisez votre méthode toString()- en plus de la journalisation et vous ne voulez pas que certaines choses apparaissent là-bas. Comme Hulk l'a déclaré, vous pouvez également vous assurer que certaines choses ne figurent même pas dans les journaux.

Mais ceux-ci étaient plutôt maquillés. Lors des derniers projets, je n'ai pas testé toString() et equals ou hashCode seulement rarement, car cela n'était pas jugé nécessaire et tout le monde était d'accord.

Tout peut se résumer comme suit: dans quelle mesure voulez-vous que votre code soit sûr et combien en vaut la peine pour vous (ou votre entreprise ou votre client ;-))

11
Roland

Le problème avec IDE généré hashCode/equals est qu'il peut ne pas être synchronisé avec l'objet lui-même (par exemple lorsque vous ajoutez de nouveaux champs). Je conseillerais donc de créer des tests pour hashCode et equals.

Il serait bien sûr sous-optimal de les écrire à la main. Vous pouvez utiliser des outils automatisés tels que le projet EqualsVerifier pour les transformer en une couche.

toString est une bête différente car aucun contrat n'est défini. Si vous utilisez toString uniquement pour obtenir une expérience de débogage plus agréable, je ne le testerais pas et le supprimerais simplement des calculs de couverture.

7
Karel Petranek

Oui, je testerais tout cela. Ce n'est pas assez bon pour dire, pas besoin de tests car ils sont générés automatiquement. Quelqu'un peut facilement ajouter un nouveau champ et oublier de régénérer le code égal/haché et la chaîne.

Le test sur chaîne est peut-être le plus controversé du lot, mais je pense que cela est particulièrement nécessaire si vous vous connectez à votre application.

Comme déjà suggéré par d’autres, EqualsVerifier est probablement la meilleure approche pour tester equals et le code de hachage.

Pour tester la méthode toString, essayez ToStringVerifier . Le test est aussi simple que:

@Test
public void testToString()
{
    ToStringVerifier.forClass(User.class)
                  .withClassName(NameStyle.SIMPLE_NAME)
                  .verify();
}
1
Syed Belal Jafri

Ces méthodes sont inutiles par elles-mêmes. Si vous n'utilisez pas ces classes dans des collections (comme HashSet/HashMap) ou si vous ne vérifiez jamais l'égalité de ces instances de classe, vous n'avez pas besoin de tests unitaires. Et, dans ce cas, je voudrais simplement désactiver le plug-in qui les génère, comme l'a proposé @ByeBye.

Mais si vous faites réellement quelque chose, vous avez besoin de tests unitaires. Si une implémentation incorrecte peut entraîner une défaillance de votre application ou un comportement incorrect, cette implémentation doit être couverte à l'aide de tests unitaires.

0
esin88