Suche
Agile Codequalität – Teil 2

Codequalität in Alt- und Wartungsprojekten: Tests mit Mockito

Daniel Winter
©Shutterstock/Roobcio

Das Testen von Software bildet einen wichtigen Bestandteil in der Softwareentwicklung. Dabei bieten unterschiedliche Vorgehensmodelle den Entwicklern mehrere Ansätze, Komponenten zu entwickeln. Besonders bei Altprojekten sollte der Fokus auf die Testabdeckung gelegt werden. Mockito [1] kann helfen, Testfälle für alte und neu in die Anwendung zu integrierende Module zu entwickeln, ohne dass das Fachwissen zahlreicher Jahre nötig wäre. Auch der Umgang mit unerwartet auftretenden fachlichen und technischen Fehlern erfordert ein individuelles Vorgehen. Denn nicht jeder Fehler erfordert eine umgehende Behebung. Im Gegensatz dazu sollte die Dokumentation immer den aktuellen Projektstand widerspiegeln und zeitnah aktualisiert werden.

Nachdem durch die Einführung von Checkstyle und PMD in das Altprojekt ein einheitlicher Formatierungsstil erarbeitet und die Grundlage für weitere Verbesserungen an der Software geschaffen wurde, überprüfen wir im nächsten Schritt die Testabdeckung. Die Sicherstellung der fachlichen Korrektheit der Anwendung gilt als Voraussetzung, um die Codequalität weiter verbessern zu können. In neuen Projekten geschieht dies unter anderem mit der Implementierung zahlreicher Unit-, Regressions- und Integrationstests. Zusätzlich besitzt das Projektteam bei der Umsetzung die Möglichkeit, unterschiedliche Vorgehensmodelle (Test First vs. Test Last) einzusetzen. Die Entwickler von Altprojekten sind gezwungen, Testfälle für historischen Code nachträglich zu implementieren. Ausnahmen bilden anstehende Erweiterungen. Hier kann auch der Ansatz von TDD (Test-driven Development) [2] verfolgt werden.

Artikelserie
Teil 1: Erste Lösungsansätze mit Checkstyle, PMD und einem Code-Formatter
Teil 2: Höhere Testabdeckung mit Mockito

Testen mit Mockito

Ein Hauptproblem bei der Testfallerstellung von Altcode ist das unvollständige Wissen über das Verhalten komplexer Komponenten infolge fehlender oder unzureichender fachlicher Dokumentation. Ebenso erschwert die schiere Größe einiger Interfaces, Klassen und Methoden die vollständige Testabdeckung. Müssen anstehende Erweiterungen, aufbauend auf solch komplexen Datenstrukturen, entwickelt werden, ist eine intensive Einarbeitung für das Verständnis nötig und ein erhöhter Zeitaufwand für die Implementierung einzuplanen. Durch den Einsatz von Mockito kann eine deutliche Verkürzung beider Phasen erreicht werden.

Mockito ist eine Bibliothek, mit der Klassen samt ihrer Funktionalität nachgebildet werden können (Mock-Objekte), ohne ihren kompletten Funktionsumfang selbst implementieren zu müssen. Der Entwickler entscheidet selbst, welche Werte oder Objekte er bei den einzelnen Methoden zurückgeben lassen will. Weiterhin besteht die Möglichkeit eines „partiellen Mockings“ (Spy) von Objekten. Dabei wird ein so genannter „Spion“ erzeugt, der die tatsächlichen Methoden des Objekts aufruft, solange deren Funktionen nicht „gemockt“ wurden. Weiterführende Informationen und konkrete Anwendungsbeispiele können der offiziellen Webseite [3] entnommen werden.

Die Anwendung von Mockito soll am Beispiel einer seit Jahren zuverlässig arbeitenden Finanzsoftware verdeutlich werden. Eine Hauptaufgabe der Anwendung ist die Erstellung von Refinanzierungen und Tilgungsplänen, basierend auf den Daten von Leasingverträgen und Leasinggesellschaften. Um auch die zukünftige Nutzung zu gewährleisten, muss die Software mit einem neuen Modul erweitert werden, das SEPA-Lastschriften [4] auswertet und einen Abgleich mit dem eigenen Bestand durchführt. Vorausetzung des Abgleichs ist die Ermittlung der IBAN, einer Kombination aus Kontonummer, Bankleitzahl und Länderkennung des Kontos der Leasinggesellschaft. In der SEPA-XML-Datei wird IBAN als ID verwendet. Die korrekte Berechnung muss daher mit einer umfassenden Testabdeckung einhergehen. Jedoch wurden in der Finanzsoftware die zentralen Klassen Leasinggesellschaft, Bankverbindungsdaten und deren Interfaces über die Zeit immer wieder erweitert und umfassen aktuell einige hundert Methoden. Zusätzlich sind die benötigten Setter und Getter der Bankverbindungsdaten mit einem direkten Datenbankzugriff versehen. Durch diese Umstände erweist sich die Testfallgestaltung als komplex und unübersichtlich. Mockito präsentiert sich in diesem Fall als die eleganteste Möglichkeit, um die Funktionalitäten des SEPA-Abgleichs zu testen.

Dabei werden, wie in Listing 1 dargestellt, einmalig die Leasinggesellschaft und die Bankverbindungsdaten in der setup-Methode „gemockt“. In den einzelnen Testfällen können mit wenigen Zeilen Quellcode die Kontonummer und die Bankleitzahl ausgetauscht und mehrere Testszenarien abgedeckt werden. Dabei kann auf für den Testfall nebensächliche Tätigkeiten, wie das umständliche Bereitstellen unterschiedlicher Bankverbindungsdaten oder die Implementierung einer Leasinggesellschaft, verzichtet werden. Ebenso entfällt eine zeitintensive Einarbeitung in die Fachlichkeit der LG-Klasse. Mockito erlaubt eine Fokussierung auf das eigentliche Problem und ist dadurch ideal geeignet, Unit-Testfälle in Altprojekten einzuführen.

/*
 * Klasse, die die IBAN aus Kontonummer und BLZ errechnet
 */
private IBANCalculator calc;
/*
 * Bankverbindungsdaten der Leasinggesellschaft
 */
private Bankverbindungsdaten bvdaten;
/*
 * Leasinggesellschaft
 */
private LG lg;

@Before
protected void setup() throws Exception {
  this.calc = new IBANCalculator();

  // Mocken der Leasinggesellschaft
  this.lg = Mockito.mock(LG.class);
  // Mocken der Bankverbindungsdaten
  this.bvdaten = Mockito.mock(Bankverbindungsdaten.class);
  Mockito.doReturn(this.bvdaten).when(lg).getBankverbindungsdaten();
}

/*
 * Bestimmung der IBAN aus einer normalen Kontonummer und BLZ. 
 */
@Test
public void testCalculateIBAN() throws Exception {
  /* 
  * Wenn die Kontonummer abgefragt wird, wird der Wert 0648489890 als String
  * zurückgegeben
  */
  Mockito.doReturn(“0648489890“).when(bvdaten).getKontonummer();
  /*
   * Wenn die BLZ abgefragt wird, wird der Wert 50010517 als String zurückgegeben
   */
  Mockito.doReturn("50010517").when(bvdaten).getBLZ ();
  // Bei der Länderkennung wird "DE" zurückgegeben
  Mockito.doReturn("DE").when(lg).getLaenderkennung();

  // calculateIBAN ruft die oben gemockten Methoden auf um die IBAN zu ermitteln
  assertEquals("DE12500105170648489890", calc.calulateIBAN(this.lg));
}

/**
 * Bestimmung der IBAN aus einer Kontonummer und BLZ mit Leerzeichen. 
 */
@Test
public void testCalculateIBANWithValidWhitespaces() throws Exception {
  Mockito.doReturn("140 015 18 ").when(bvdaten).getKontonummer();
  Mockito.doReturn("130 000 00 ").when(bvdaten).getBLZ ();
  Mockito.doReturn("DE").when(lg).getLaenderkennung();

  assertEquals("DE26130000000014001518", calc.calculateIBAN(this.lg));
}

//... Implementierung weiterer Testfälle

Aufmacherbild: Test handwritten with white chalk on a blackboard von Shutterstock / Urheberrecht: Roobcio

[ header = Seite 2: Einarbeitung mittels Testen ]

Einarbeitung mittels Testen

Versucht man während der Fehlerbeseitigung konzentriert allein an der Komponente des Problems zu arbeiten, sind bei der Einarbeitung in ein Modul alle Klassen, die die Fachlichkeit betreffen, von Relevanz. Ein tieferes Verständnis für die Funktionsweise lässt sich durch ein simples Code-Review nur schwer erreichen, ist jedoch eine Voraussetzung zur Verbesserung der Codequalität durch die Einführung neuer und komplexerer Unit Tests. Als Beispiel wird die Erstellung von Tilgungsplänen für Refinanzierungen näher betrachtet. Diese Thematik stellt einen zentralen Bestandteil der bereits genannten Finanzsoftware dar. Auf den ersten Blick erscheint die Berechnung der einzelnen Tilgungsplanzeilen für jemanden, der in dem Thema unerfahrenen ist, sehr komplex und unübersichtlich. Um trotzdem die Thematik verstehen und gegebenenfalls notwendige fachliche Änderungen am Quellcode vornehmen zu können, bietet sich die Erstellung eigener Testfälle mithilfe von Mockito an. Dabei ist zu Beginn nicht beabsichtigt, einen korrekt kalkulierten Tilgungsplan zu erzeugen, sondern wichtig ist nur die Tatsache, dass überhaupt ein Tilgungsplan berechnet oder dass die Erstellung mit einer Exception scheitern wird. Entgegen dem Vorgehen bei einem normalen Unit Test, kennt der Entwickler das Ergebnis nur grob. Ja, es ist sogar ungewiss, ob das endgültige Resultat einen brauchbaren Testfall abbildet. Die Gefahr bei dieser Art der Einarbeitung in eine unbekannte Fachlichkeit mithilfe von Unit Tests besteht darin, die eigentlich unbekannten Resultate als fachlich korrekt zu betrachten, daraus falsche Schlussfolgerungen zu ziehen, andere Testfälle darauf aufzubauen und den Eindruck zu erwecken, dass Kernkomponenten des Altprojekts korrekt getestet wären. Der Entwickler ist sich dieser Problematik durchaus bewusst, denn er hatte auch nicht vorgehabt, die Testabdeckung zu verbessern, sondern nur die Einarbeitung zu erleichtern. Gefährlich wird es allerdings, wenn spätere Mitarbeiter das Vorhandensein von Testfällen zum Anlass nehmen, Refactorings von Methoden und Klassen vorzunehmen. Deswegen sollten die erstellten Testklassen immer mit @Ignore gekennzeichnet und zusätzlich mit hinweisenden Kommentaren versehen werden.

In Listing 2 wird beispielhaft ein erster Testfall für die Tilgungsplanberechnung erstellt. Der Fokus liegt auf  der Grundlage jedes Tilgungsplans, der KontoParameter-Klasse. Das Ziel ist der Aufbau des Wissens über die notwendigen Werte für eine fehlerfreie Erstellung, nicht das Eruieren des Einfluss einzelner Kontoparameter auf die Zeilen des Tilgungsplans. Durch das Mocken der Methoden (getZinssatz(), getZinsmethode() u. a.) und das Verändern der Rückgabewerte erhält der Entwickler einen ersten Eindruck über das Verhalten der Tilgungsplan-Klasse. Das Fehlschlagen des Tests könnte zum Beispiel mit null als Rückgabewert provoziert werden.

/*
 * Einarbeitungstest um einen einfachen Tilgungsplan zu erstellen.
 * ACHTUNG: Bildet keinen validen Unit-Test ab.
 */
@Ignore
public void testCalculateSimpleTilgungsplan() throws Exception() {
  KontoParameter kp = Mockito.mock(KontoParameter.class);
  // Mocken der Kontoparameter angefangen bei Zinssatz und Zinsemthode
  Mockito.doReturn(4.0).when(kp).getZinssatz();
Mockito.doReturn("30_360").when(kp).getZinsmethode();
  // Mocken weitere wichtiger Parameter wie Zahlungshäufigkeit...

  Tilgungsplan tp = new Tilgungsplan(kp);
  // Holen der leeren Liste mit den eigentlichen Zeilen des Tilgungsplans
  List<TPZeilen> tpZeilen = tp.getTPZeilen();

  // Tilgungsplan existiert, ist aber leer => Test erfolgreich
  Assert.assertNotNull(tpZeilen);
  Assert.assertEquals(0, tpZeilen.size());
}

Aufbauend auf diesen Erkenntnissen erstellen wir im folgenden Schritt einen Tilgungsplan mit monatlichen Zahlungen (Listing 3). Dafür wird dem Testfall der „Spy“ der Zahlungsreihe einer Refinanzierung hinzugefügt. Die Notwendigkeit des Spy besteht in der komplexen, vom Tilgungsplan genutzten Finanzmathematik der Zahlungsreihe, die mit dem aktuellen Wissen des Entwicklers nicht adäquat gemockt werden könnte. Ausschlaggebend ist die Erkenntnis, dass die Methode getZahlungen() einen direkten Einfluss auf die Zeilen des Tilgungsplans besitzt, anders als die Angabe der Anzahl der Vorperioden, die aber ebenfalls benötigt wird.

@Ignore
public void testCalculateNotSoSimpleTilgungsplan() throws Exception {
  //Mocken der Kontoparameter wie in Listing 1
  KontoParameter kp = Mockito.mock(KontoParameter.class);
  //Mocken von Zinssatz, Zinsmethode 

  //Datumsangaben werden für die Zahlungsreihe benötigt 
  final FinanzDatum valuta = new FinanzDatum(1, 1, 2013);
  final FinanzDatum ersteZahlung = new FinanzDatum(1, 2, 2013);

  //Erstellen einer Zahlungsreihe und Erzeugen eines Spions 
  final Zahlungsreihe zr = new Zahlungsreihe(valuta, ersteZahlung, kp);
  final Zahlungsreihe spyZr = Mockito.spy(zr);

  //Mocken der für den Tilgungsplan wichtigen Methoden
  Mockito.doReturn(1).when(spyZr).anzahlVorperioden(Mockito.any(FinanzDatum.class));
  final double[] zahlungen = new double[] {500, 600, 700, 800, 900, 1000};
  Mockito.doReturn(zahlungen).when(spyZr).getZahlungen();

  Tilgungsplan tp = new Tilgungsplan(kp);
  tp.addRefinanzierungsZahlungsreihe(spyZr);

  //Tilgungsplan existiert und hat sieben Zeilen (sechs Zahlungen plus den Monat
  //ohne Zahlung, hier der 1.1.2013) 
  Assert.assertNotNull(tpZeilen);
  Assert.assertEquals(7, tpZeilen.size());
  //weitere Überprüfungen oder auch eine Ausgabe des Tilgungsplans 
  //zur Analyse möglich
}

In weiteren Testfällen kann der Entwickler die Beschaffenheit der Zahlungsreihe analysieren, indem er zum Beispiel Wissen über die angesprochenen Vorperioden aufbaut oder eine vorzeitige Ablösung dem Tilgungsplan hinzufügt. Pro Testfall sollte der Fokus auf ein konkretes Problem gelegt werden. Die Komplexität der Testfälle kann mit dem wachsenden fachlichen Wissen immer weiter ausgebaut werden. Indem der Entwickler Schicht für Schicht die Arbeitsweise einzelner Komponenten versteht, erreicht er nicht nur ein besseres Verständnis für das komplizierte Gesamtsystem, das die Grundlage für umfassende, tatsächliche Unit Tests bildet, sondern schafft gleichzeitig einen hervorragenden Einstiegspunkt in die Anwendung für neue, unerfahrene Entwickler. Diese haben die Möglichkeit, ihre eigenen Testfälle, basierend auf den vorhandenen, zu entwerfen, bestehende Einarbeitungstestfälle zu richtigen Unit Tests auszubauen und dabei die Robustheit des Systems weiter zu verbessern.

[ header = Seite 3: Fehler dokumentieren ]

Fehler dokumentieren

Die Fehlersuche und Behebung umfasst den größten Teil des Wartungslebenszyklus von Software – seien es Schwierigkeiten mit der Performance durch stark ansteigende Datenströme und stetig wachsende Datenbanktabellen, sporadisch auftretende Probleme mit der Nebenläufigkeit oder Bugs in den neuentwickelten Erweiterungen. Im Idealfall analysiert der Entwickler gedanklich zuerst den Problemfall, versucht den Fehlerursprung auf wenige Klassen einzugrenzen, sondiert mögliche Lösungsvarianten und implementiert die optimale Variante, um den Ausfall des Produktivsystems so kurz wie möglich zu halten. Neue Projekte mit einer klaren Architektur, genau definierten Schnittstellen und einer umfangreichen Dokumentation sind dabei leichter zu warten als historisch gewachsene und bereits mit zahlreichen Bugfixes ausgestattete Wartungsprojekte. Der Idealfall kann durch die bescheidene Codequalität nur selten in Betracht gezogen und damit ausgeschlossen werden. Vielmehr ist es von Vorteil, zuerst zu analysieren, welche Art von Fehler genau vorliegt.

Bei vom Kunden gemeldeten technischen Problemen ist meist davon auszugehen, dass die Ursachen im eigenen Quellcode zu finden sind, besonders, wenn im Vorfeld Patches ausgeliefert wurden. Die Fehlersuche kann sich hierbei auf die geänderten Klassen beschränken, die durch die Versionsverwaltung identifiziert werden können. Nicht so trivial gestaltet sich die Analyse von fachlichen Fehlern, wie die Übertragung falscher Werte in ein angebundenes Fremdsystem. Ein reger Austausch mit der Fachabteilung des Kunden und eine detaillierte Schilderung der eigentlichen Programmlogik können zu einer raschen Aufklärung beitragen und klären, ob ein Bedienungsfehler oder ein jahrelang unentdecktes technisches Problem vorliegt. Notwendige Änderungen am Quellcode sollten dabei immer in Verbindung mit einer ausführlichen Dokumentation realisiert werden. Zwingend erforderlich werden detaillierte Beschreibungen bei Schnittstellen zu Fremdsystemen.

Bei weitem schwieriger zu beheben, aber auch seltener sind technische Fehler, die bei der Wartung oder Weiterentwicklung der Altsoftware vom Entwicklerteam in den Kernkomponenten gefunden werden. Diesen Bugs liegt meist ein Designfehler oder ein unbekanntes Nebenläufigkeitsproblem zugrunde. Ein besonderes Merkmal dieser Art von Fehler ist das bisherige Nichtauftreten im Betrieb. Somit ist auszuschließen, dass kritische Anwendungsfälle betroffen sind, die einen Ausfall des Systems verursachen könnten. Eine Behebung des Fehlers sollte deshalb mit Bedacht geschehen. Mögliche Auswirkungen auf andere Komponenten des Altsystems müssen zuerst analysiert werden, um eine Abschätzung über den möglichen Aufwand treffen zu können. Eine Überprüfung der Testabdeckung der betroffenen Module gibt Aufschluss, ob nach einem Refactoring die fachliche Korrektheit des Systems garantiert werden kann. In jedem Fall muss ein entsprechender Eintrag in der Fehlerverwaltung und im Wiki verfasst werden, der Auskunft über die Ursache, Auswirkungen und Lösungsansätze des Problems bietet. Dadurch ist sichergestellt, dass eine Behebung zeitnah oder zu einem späteren Zeitpunkt erfolgen kann.

[ header = Seite 4: Pflege der Dokumentation ]

Pflege der Dokumentation

Die Dokumentation ist die zentrale Komponente, um neue Mitarbeiter einzuarbeiten, Bugs zu beheben, Sonderfälle im Code zu identifizieren und neue Erweiterungen zeitnah in das Altprojekt integrieren zu können. Leider stellt sie auch den am häufigsten vernachlässigten Bereich dar – angefangen bei einer Anleitung zur Einrichtung des Workspace über eine technische und fachliche Beschreibung der Kernkomponenten der Anwendung, Aufbau oder Erhalt des eigenen Datenwikis bis hin zu ausführlichen Codekommentaren. Mit hoher Sicherheit haben alle Abschnitte Verbesserungspotenzial oder müssen in entscheidenden Punkten aktualisiert werden.

Ein guter Einstieg für den Neuaufbau ist die Erstellung der Anleitungen zur Einrichtung des Workspace und die Installation und Einrichtung zusätzlich benötigter Software. Anhand der eigenen Erfahrung können die nötigen Schritte und möglichen Fehlerquellen rekonstruiert werden und erlauben die Erstellung einer detaillierten Anleitung. Die technische und fachliche Beschreibung der Anwendung sollte dagegen nur von einem erfahrenen Entwickler vorgenommen werden. UML-Tools und deren Eclipse-Plug-ins [5] können durch die Generierung von Klassendiagrammen einen ersten Überblick über die Architektur bieten und helfen, Komponenten voneinander abzugrenzen oder deren Schnittstellen zu identifizieren. Auch eine schematische Darstellung der Datenbanktabellen unterstützt den Verständnisprozess. Abschließend ermöglicht ein Wiki die Bereitstellung und Archivierung aller erstellten Dokumente und Diagramme. Bei einer Neuinstallation des Wikis muss auf eine saubere und komplette Datenmigration geachtet werden. Nichts ist frustrierender als der Umstand, noch mehr Zeit und Aufwand in den Erhalt von überarbeitungswürdigen Dokumenten zu investieren.

public void doSomething()

Verständlicher Quellcode in Verbindung mit aussagekräftigen Kommentaren bildet das Grundgerüst, um eine problemlose Wartung von Altprojekten zu gewährleisten. Durch die Mitarbeit vieler Entwickler zu unterschiedlichen Zeiten und mit eigenen Vorstellungen der Quellcodeformatierung sinkt die Verständlichkeit des Quellcodes. Gleichzeitig werden, bedingt durch den zusätzlichen Zeitdruck, neue Kommentare nicht verfasst und bereits bestehende angepasst. Eine nachträgliche Bearbeitung und Korrektur dieser Problematik ist nur selten möglich. Gründe hierfür sind die pure, nicht zu bewältigende Masse an unkommentiertem Quellcode und die Unkenntnis über den eigentlichen Zweck von Methoden nach zahlreichen Erweiterungen, Bugfixes und kryptischen Variablenbezeichnungen. Besonders heikel erweist sich das Nichtkommentieren von Sonderfällen. Hier ist neben einer aussagekräftigen Beschreibung (wieso und was) auch die entsprechende Bug-ID – falls vorhanden – Pflicht. Spätere Erweiterungen sind auf exakte Schilderungen dieser Sonderfälle angewiesen. Insgesamt bilden Erweiterungen und Patches mitunter die einzige Möglichkeit, mit der Tradition zu brechen und eine vollständige Dokumentation von Code sicherzustellen oder Namenskonventionen für Klassen und Variablen einzuhalten. Die nachträgliche Kommentierung von altem Quellcode sollte nur von erfahrenen Entwicklern vorgenommen werden, die im besten Fall selbst Testfälle für die betreffenden Klassen verfasst haben.

[ header = Seite 5: Erhalt der Codequalität ]

Erhalt der Codequalität

Der letzte und besonders für nachfolgende Entwickler essenziell wichtige Schritt umfasst den Erhalt der Codequalität. Um zu verhindern, dass die durchgeführten Maßnahmen, wie die Einführung von Checkstyle, PMD und einheitlichen Formatierungsregeln, einmalige Aktionen bleiben, müssen Vorkehrungen zum Erhalt getroffen werden. Eine Aktualisierung des Build-Systems mit der Verwendung der Checkstyle- und PMD-Plug-ins stellt die Integrität der festgelegten Regelsätze sicher. Die lokale Installation und Pre-Commit-Verwendung der dazugehörigen Eclipse-Plug-ins verringert zusätzlich das Auftreten von Warnungen aufgrund falsch formatierter Klassen. Doch nicht nur das Altprojekt benötigt umfassende Wartungsarbeiten, um einen stabilen Programmablauf zu garantieren, auch die Einträge und Dokumente des Datenwikis sollten in zyklischen Abständen überprüft und gegebenenfalls umgeschrieben werden. Der Einsatz der Tools Vagrant [6] und Puppet [7] ist ebenfalls eine Überlegung wert, um eine einheitliche Arbeitsumgebung bei allen Teammitgliedern sicherzustellen. Aber bereits mit den in beiden Artikeln beschriebenen Maßnahmen, ausreichender Motivation, bewilligter Zeit und Budget kann durch eine Codequalitätsverbesserung die Produktivität im Altprojekt signifikant und nachhaltig verbessert werden.

Geschrieben von
Daniel Winter
Daniel Winter
Daniel Winter studierte Informatik an der FH Zittau/Görlitz und arbeitet seit 2011 als Consultant für Softwareentwicklung bei der Saxonia Systems AG (daniel.winter@saxsys.de). Sein aktueller Fokus liegt in den Möglichkeiten der Codequalitätsverbesserung bei Projekten jedweder Art. Ausgiebige Erfahrungen in diesem Bereich sammelte er bei der Wartung einer Leasing-Refinanzierungssoftware.
Kommentare
  1. Trepper2013-11-27 15:39:30

    Hinterfragt eigentlich niemand mehr die Frameworks? Die Herde trabt gerade zu Mockito, aber JMockit bietet wesentlich mehr und mit einem konsistenteren API. Man kann damit z. B. auch statische Methoden ohne Klimmzüge mocken.

    https://code.google.com/p/jmockit/wiki/MockingToolkitComparisonMatrix

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.