Unit Testing ist gleich und Hashcode - eine Komplexität Geschichte

8

Ich habe ein moralisches Dilemma. Ich habe einige Wertobjekte in meiner Anwendung, die unveränderlich und extrem einfach sind. Ich habe den equals und den hashcode mit einer IDE generiert (intellij in meinem Fall), aber das hat dazu geführt, dass die code coverage abfällt, und die Berichte zeigen nun, dass diese Wertobjekte sehr komplex sind (mit zyklische Komplexität metrisch), wenn sie tatsächlich tot einfach sind.

Als ein Beispiel ist das folgende equals in einem Wertobjekt, das 3 unveränderbare Attribute hat. Die Code-Komplexität ist 14 (javaNCSS) und es gibt 26 Ausführungszweige (Cobertura). Ich sollte auch hinzufügen, dass ich den Build fehlschlagen, wenn eine Methode eine Komplexität von mehr als 10 hat.

%Vor%

Ich frage mich, was andere Entwickler verwenden, um dies zu umgehen, da ich den Komplexitätsberichten ziemlich viel Aufmerksamkeit schenke, da sich eine hochkomplexe Metrik nach meiner Erfahrung auf mehr Bugs bezieht, also diese automatisch erzeugten Gleichen und Hashcodes Verschmutzung der Berichte.

Ich denke EqualsBuilder und HashcodeBuilder von Apache commons-lang zu verwenden, um dies zu umgehen, aber ich bin nicht 100% glücklich: S.

Bearbeiten

Ich hätte hinzufügen sollen, dass der Teil des Codes, den ich für dieses Projekt schreibe, eine Bibliothek ist, die von anderen Geschäftseinheiten verwendet wird ... Und auch von einem anderen Team gepflegt wird: S.

    
Augusto 23.04.2011, 13:18
quelle

7 Antworten

7
  

Ich denke EqualsBuilder und HashcodeBuilder von Apache commons-lang zu verwenden, um dies zu umgehen, aber ich bin nicht 100% glücklich: S.

Warum nicht diese verwenden?

Die Verwendung von ihnen reduziert die Größe und Komplexität Ihrer eigenen Methoden und es ist viel einfacher visuell zu überprüfen, dass equals und hashCode konsistent implementiert werden.

Es ist natürlich auch eine gute Idee und ziemlich einfach zu testen, dass der equals / hashCode-Vertrag erfüllt ist, also schreiben Sie auf alle Fälle Tests.

    
Don Roby 23.04.2011, 13:40
quelle
5

Ich denke, dass Ihr wirkliches Problem darin besteht, zu viel Vertrauen in künstliche Maße wie die zyklische Komplexität der Codeabdeckung zu setzen.

Die einfachen Fakten sind:

  • der generierte Code ist korrekt ... modulo, dass Sie das korrekte Modell der Gleichheit gewählt haben, und
  • Der generierte Code ist nicht kompliziert ... oder zumindest nicht komplizierter als er sein muss.

Lernen Sie, Ihrem eigenen Urteilsvermögen zu vertrauen, und hören Sie auf, sich auf Werkzeuge zu verlassen, um Ihre Designentscheidungen für Sie zu treffen.

Und die logische Folge dessen, was ich gerade gesagt habe, ist, dass, wenn Sie denken, dass Sie den generierten Code vereinfachen können (und sollten), während Sie immer noch sicherstellen, dass er für Ihre aktuellen und geplanten Anwendungsfälle korrekt ist >

Übrigens ist ein erzeugtes equals / hashcode-Paar wahrscheinlich wahrscheinlicher korrekter als ein handgeschriebenes ... geschrieben von einem "durchschnittlichen Bär" -Programmierer. Beachten Sie beispielsweise die sorgfältige Verarbeitung des generierten Codes für Nullfelder und den Vergleich der Typen. Viele Entwickler würden das nicht richtig machen.

    
Stephen C 23.04.2011 13:41
quelle
3

Es gibt einen Widerspruch hier. Sie haben überhaupt keinen Grund, sich über die Komplexität von automatisch generiertem Code Gedanken zu machen. Es ist die Handcodierung, über die Sie sich Sorgen machen sollten.

    
EJP 23.04.2011 13:21
quelle
3

Wie hoch ist Ihre Codeabdeckung? Einige Leute argumentieren, dass das Schießen für 100% ein Zeichen für anale Remanenz ist. Wenn Sie in der 70-80% -Bereich sind, und Sie wissen, dass das, was Sie nicht getestet haben, kein Problem ist, warum sich dann darum kümmern?

Andererseits sind diese Tests nicht so schwer zu schreiben. Warum schreibst du sie nicht, sei damit fertig und schläfst in der Nacht? Sie hätten den Test in der Zeit beendet, die nötig war, um hier Ihr moralisches Dilemma einzugeben und auf Antworten zu warten.

    
duffymo 23.04.2011 13:24
quelle
3

Ich denke, Ihre Ziele mit geringer Komplexität und hoher Abdeckung sind bewundernswert. Ich habe festgestellt, dass die Google Guava -Bibliothek bei dieser Art von Problem (und auch bei anderen Problemen) sehr nützlich ist schreibe folgendes:

%Vor%

Sie können dann die EqualsTester , um schnell über diese Methode zu berichten. Sie erhalten Einfachheit und Testabdeckung. Danke an diese SO-Frage , die mir hilft, EqualsTester zu finden.

Eine andere Option, die ich seit kurzem benutze, ist Lombok . Lombok ist eine großartige Bibliothek zum Schreiben unveränderlicher Wertobjekte. Hier ist eine Beispiel-Lombok-Klasse:

%Vor%

Die Annotation @Data bewirkt, dass Lombok eine Menge Code für Sie generiert. Sie erhalten Getter (und für nicht endgültige Felder) Setter. Sie erhalten equals, hashCode und toString. Sie erhalten einen Konstruktor für alle Argumente. Und alle diese Methoden werden automatisch aktualisiert, wenn Sie die Feldliste ändern. Ich habe Hunderte von Zeilen aus meinem aktuellen Projekt mit Lombok getrimmt und meine Wertobjekte sind jetzt immer komplett implementiert.

    
Spina 23.07.2012 20:32
quelle
1

Einfache POJOs - unveränderlich mit oder ohne Builder oder veränderbar - werden bestenfalls automatisch aus einer einfachen DSL-Beschreibung erzeugt, bis Java direkte Sprachunterstützung für dieses einfache, aber wichtige Feature erhält.

    
yeoman 13.05.2013 22:10
quelle
0

Meiner Meinung nach ist ein Rückgang der Codeabdeckung ein Indikator dafür, dass Sie sich den Code ansehen und selbst herausfinden sollten, ob der Rückgang der Abdeckung gerechtfertigt ist. Code-Metriken für Dinge wie generierte Gleichheit oder Hashcode sind nicht wirklich wichtig, sie sind so einfach, dass sie einfach funktionieren. Das gleiche gilt für einfache Getters und Setter, denen es wirklich wichtig ist, wenn einige von ihnen nicht abgedeckt sind? (Das kann ein Symptom für etwas anderes sein, das nicht getestet wird, aber das ist nebensächlich).

Werkzeuge sind hier, um uns zu helfen, guten Code und Anwendungen zu schreiben ... wir sollten keine Sklaven für sie sein.

    
Eric-Karl 23.04.2011 13:49
quelle