
Prinzipien und Tests – Das Seminar wendet sich an Softwareentwickler, die gerade beginnen, sich mit dem Thema Softwarequalität auseinanderzusetzen. Es werden die wichtigsten Prinzipien und Praktiken der Clean Code Developer Initiative vermittelt.
Bei diesem Beitrag handelt es sich um eine überarbeitete Version. Er wurde zuvor bereits bei refactoring-legacy-code.net veröffentlicht.
Dies ist eine Beitragsserie. Die weiteren Beiträge finden Sie hier:
Um automatisierte Tests ergänzen zu können, ist es manchmal sinnvoll, einen Internal Test Constructor mit einem Konstruktorparameter einzuführen, über den die Abhängigkeit von außen reingereicht werden kann. Die folgende Methode kann nicht gut automatisiert getestet werden, da sie eine Abhängigkeit von der aktuellen Zeit, hier in Form der DateTime.Now Eigenschaft, hat.
public string Format(string message) { return DateTime.Now + ": " + message; }
Die Testbarkeit kann hergestellt werden, indem der Aufruf der statischen DateTime.Now Methode über eine Func beeinflussbar gemacht wird. Dazu führen Sie zunächst ein Feld ein:
private Func now = () => DateTime.Now;
Anschließend ersetzen Sie alle DateTime.Now Aufrufe durch Aufrufe von now():
public string Format(string message) { return now() + ": " + message; }
Dieses Refactoring ist nicht vollständig toolgestützt durchführbar, insofern ist hier Vorsicht geboten. In jedem Fall sollten Sie vor diesem Refactoring den Stand des Quellcodes in der Versionskontrolle ablegen. Ferner sollten Sie den Stand nach dem Refactoring dort ablegen, so dass die Differenz in der Versionskontrolle exakt dieser Veränderung am Quellcode entspricht. So ist es möglich, diesen Schritt später wieder rückgängig zu machen, sollte sich ein Fehler eingestellt haben.
Um nun das Verhalten von außen im Test beeinflussen zu können, machen Sie das Feld now über den Internal Test Constructor zugänglich. Damit sich durch den zusätzlichen Konstruktor das Verhalten des restlichen Softwaresystems nicht verändert, ergänzen Sie zusätzlich einen parameterlosen Defaultkonstruktor, der die Lambda Expression zur Initialisierung des Feldes an den internen Test Konstruktor übergibt.
public class FormattingService { private readonly Func now; public FormattingService() : this (() => DateTime.Now) { } internal FormattingService(Func now) { this.now = now; } public string Format(string message) { return now() + ": " + message; } }
Führen Sie einen zusätzlichen Konstruktor mit Parametern ein, um die Testbarkeit einer Klasse zu erhöhen.
Häufig existieren in Legacy Code Projekten direkte Abhängigkeiten zwischen Klassen. Dadurch wird das automatisierte Testen erschwert. Durch die Einführung eines Interface mit dem Extract Interface Refactoring kann im Test leichter mit Attrappen gearbeitet werden. Im folgenden Beispiel hat die Klasse CheckoutService eine direkte Abhängigkeit zur Klasse PaymentService.
public class CheckoutService { private PaymentService paymentService = new PaymentService(); public void DoCheckout() { // …. paymentService.PayByCreditCard(cardNo, owner, pin, amount, description); } }
Beim Ausführen der Methode DoCheckout wird der PaymentService aufgerufen und eine Zahlung durchgeführt. Für das automatisierte Testen ist dies ungeeignet, weil dann mit jedem Testdurchlauf mit dem Zahlungsdienstleister kommuniziert würde. Durch spezielle Testdaten wäre das möglicherweise noch praktikabel, hätte aber einen sehr negativen Einfluss auf die Laufzeit und Stabilität der Tests. Daher führe ich im ersten Schritt ein Interface für die Klasse PaymentService ein. Das Ergebnis von Extract Interface:
public interface IPaymentService { void PayByCreditCard(string cardNo, string owner, string pin, double amount, string decription); }
Nun muss in der Klasse CheckoutService, die den PaymentService verwendet, eine Möglichkeit geschaffen werden, in Tests eine Attrappe zu verwenden. Dazu stellen ich die Verwendung auf das Interface statt dem konkreten Typ um. Ferner ergänze ich zwei Konstruktoren. Der öffentliche Defaultkonstruktor leitet seine Initialisierung an den internen „echten“ Konstruktor weiter. Dabei wird eine Instanz des PaymentService erzeugt, so wie es zuvor bei der Feldinitialisierung bereits der Fall war:
private IPaymentService paymentService; public CheckoutService() : this(new PaymentService()) { } internal CheckoutService(IPaymentService paymentService) { this.paymentService = paymentService; }
Das Einführen der zusätzlichen Konstruktoren entspricht der Vorgehensweise im vorigen Abschnitt, in dem wir einen DateTime.Now Aufruf durch eine Func ersetzt hatten. Neu ist hier die Einführung des Interface mittels Extract Interface.
Benutzen Sie Extract Interface, um zu einer vorhandenen Klasse ein Interface zu generieren. Durch Verwendung des Interface anstelle des konkreten Typs kann die Implementation austauschbar gemacht werden. Dies ist für das automatisierte Testen hilfreich.
Prinzipien und Tests – Das Seminar wendet sich an Softwareentwickler, die gerade beginnen, sich mit dem Thema Softwarequalität auseinanderzusetzen. Es werden die wichtigsten Prinzipien und Praktiken der Clean Code Developer Initiative vermittelt.
Mit Flow Design von den Anforderungen zum Clean Code – Lernen Sie mit Flow Design einen Softwareentwicklungsprozess kennen, der Sie flüssig von den Anforderungen zum Clean Code führt.
Test Framework – In diesem Seminar erlernen die Teilnehmer den Umgang mit einem Test Framework.
Brownfield statt grüner Wiese – Das Seminar wendet sich an Entwickler, die Bestandscode pflegen und erweitern. Sie lernen, wie mit Refactoring Maßnahmen die Code Qualität verbessert wird.
Das Big Picture – Das Seminar wendet sich an erfahrene Entwickler, die sich mit der Frage befassen, wie eine angemessene Grobstruktur für ein Softwaresystem entsteht.
Ein Team unterstützen – Dieses Seminar wendet sich an Softwareentwickler, die ihre Kollegen mit ihren Kenntnissen über die Clean Code Developer Prinzipien und Praktiken unterstützen möchten.
Seminare als Trainer durchführen – Dieses Seminar wendet sich an Softwareentwickler, die ihr Wissen über die Clean Code Developer Prinzipien und Praktiken bzw. über Flow Design als Trainer an andere weitergeben möchten.
Online CoWorking inkl. Coaching –
Wir werden häufig gefragt, was man als Entwickler tun könne, um kontinuierlich dran zu bleiben am Thema Clean Code Developer. Unsere Antwort: Treffen Sie sich regelmäßig wöchentlich online mit anderen Clean Code Developern.
Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzererfahrung bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst, und hilft unserem Team zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.
Unbedingt notwendige Cookies sollten jederzeit aktiviert sein, damit wir deine Einstellungen für die Cookie-Einstellungen speichern können.
Wenn du diesen Cookie deaktivierst, können wir die Einstellungen nicht speichern. Dies bedeutet, dass du jedes Mal, wenn du diese Website besuchst, die Cookies erneut aktivieren oder deaktivieren musst.