Java-Klassenpfad-Hölle in der Legacy-Junit-Testsuite lösen

8

Angenommen, ich habe eine ältere JUnit-Testsuite, die folgende Tests enthält:

%Vor%

Nehmen Sie nun an, dass die Awesome Mocking-Bibliothek auf der Awesome BCEL-Bytecode-Generierungsbibliothek basiert, die die Klasse org.useful.XMLClass enthält und diese Bibliothek die Version 1 von XMLClass hat.

Nehmen Sie nun an, dass die Amazing Xml-Operation auf der Amazing Xml Library basiert, die die Klasse org.useful.XMLClass enthält und diese Bibliothek die Version 2 der XML-Klasse hat.

Nehmen Sie außerdem an, dass Version 2 der Klasse nicht rückwärtskompatibel zur Version 1 ist - also welche Version im Klassenpfad eine höhere Priorität hat - sie bricht die Abhängigkeiten der anderen Version.

Nehmen Sie außerdem an, dass es 400 Tests gibt, die auf einer genialen Mocking-Bibliothek basieren - daher ist das Neuschreiben keine wünschenswerte Option.

Nehmen Sie auch an, dass einige kritische Geschäftsfunktionen mit einer erstaunlichen XML-Bibliothek erstellt wurden - und es ist sehr zu bevorzugen, dies nicht neu zu schreiben.

Wie lösen Sie diese Klassenpfad-Hölle-Situation - abgesehen davon, dass Sie die Ameisen-Tests (vorausgesetzt Sie laufen sie mit Ant) zweimal mit zwei unterschiedlich manuell geordneten Klassenwegen und manuell bestimmten Test-Untermengen durchführen? (Ich bin offen für eine Idee mit benutzerdefinierten Classloadern - aber das scheint etwa das gleiche Maß an Wartbarkeit wie der doppelte benutzerdefinierte Klassenpfad mit ant-Lösung)

    
hawkeye 28.02.2013, 12:16
quelle

2 Antworten

3

Ich glaube, dass eine ziemlich transparente Lösung mit einem Java-Agenten und einem benutzerdefinierten Klassenlader möglich ist. Die Idee ist folgende:

  1. Verwenden Sie das Instrumentation Framework (Java-Agent ) um die Klassen abzufangen, wenn sie geladen sind. Wenn Sie eine Klasse erkennen, die sich in der Awesome Mocking Library befindet, ersetzen Sie alle Verweise auf org.useful.XMLClass zum Beispiel auf intercepted.org.useful.XMLClass .
  2. Erstellen Sie einen benutzerdefinierten Klassenlader, in dem Sie überprüfen, ob die angeforderte Klasse intercepted.org.useful.XMLClass ist. Wenn dies der Fall ist, laden Sie die Version von XMLClass , die von der Mocking-Bibliothek verwendet wird. Alle anderen Anfragen können standardmäßig bearbeitet werden.

Verwenden Sie den benutzerdefinierten Klassenlader und hängen Sie den Java-Agenten an, wenn Sie die Tests ausführen, und alles sollte ordnungsgemäß ausgeführt werden, als ob kein Abhängigkeitskonflikt vorhanden wäre.

    
Steven 28.02.2013, 12:48
quelle
0

Ich denke, Steven's Antwort ist großartig - der Vollständigkeit halber und weil diese Frage so viele Stimmen bekam - wollte ich alle Alternativen teilen, von denen wir dachten (einschließlich der schlechten)

  1. Partitionieren Sie die Tests (oder einige der Tests) in eine andere Klassenpfad-Reihenfolge (Nachteil - könnte dazu führen, dass Sie andere wichtige Probleme mit Ihren Tests verpassen - keine praktikable Option)
  2. Rollback Amazing XML-Operation und implementieren Sie eine andere Möglichkeit (angesichts der Investition in die Verwendung von diesem und die Tatsache, dass andere Operationen erschöpft waren - wurde dies abgelehnt)
  3. Schreiben Sie die Tests mit einer neuen Mocking-Bibliothek um (das ist auf lange Sicht gut - auf kurze Sicht ist es größer als unser aktuelles Projekt, weil es Hunderte und Hunderte gibt)
  4. Erstellen Sie eine angepasste Version der erstaunlichen Mocking-Bibliothek, die die neuere Version von org.useful.XMLClass verwendet (dies stellte sich als größer heraus als unser aktuelles Projekt)
  5. Extrahiere die betreffende Klasse aus der Quelle und lege die ältere Version auf den Test-Klassenpfad, wobei die Quellbibliothek überschrieben wird (es stellte sich heraus, dass dies mit mehreren anderen Klassen verflochten war - also nicht-trivial)
  6. Verwenden Sie Stevens fantastische Idee oben - wieder erwies sich das als nicht-trivial
  7. Setzen Sie die Tests mit @Ignore - und setzen Sie sie in die Warteschlange, um sie in einem zukünftigen Projekt neu zu schreiben.
hawkeye 01.03.2013 10:19
quelle

Tags und Links