gibt es nicht nur ein AddBook(), sondern sicher auch noch ein GetBook() oder eine ganzeCollection von Books, über die man prüfen kann, ob eine Zustandsveränderung wirksam war.Der KataPotter-Warenkorb braucht solche Zugriffsroutinen aber nicht. Warum sollten sie also nur für den Test eingeführt werden? Ich halte nichts davon, weil sie das Interface des system under testaufblähen. Sie haben keinen Wert für die Domäne, sind in der Intellisense-Liste der Eigenschaftenund Methoden aber immer sichtbar. Da hilft auch die Deklaration als intern nicht viel. Das wärefalsch verstandenes Design for Testability.Wenn Sie die KataPotter so wie oben gezeigt angehen sollten, widerstehen Sie der Versuchung,dem Warenkorb z.B. eine Count-Eigenschaft zu geben, um den Test zum Laufen zu bekommen.Solch ein Design wäre dann zwar irgendwie testbarer, aber die Flexibilität würde sich nichterhöhen. Sie hätten nicht mehr das minimal Notwendige getan. Außerdem würde der Test dannzweierlei testen. Das ist zu vermeiden! Er würde AddBook() und Count prüfen. In beiden könnten ja Fehler stecken.AddBook() und Count wären sogar gegenseitig abhängig in Bezug auf Tests. Sie könnten auchCount nicht zuerst testen, denn dazu müssten Sie Zustand aufbauen. Wäre das nicht der Fall, ist die Nutzung von mehreren SUT-Funktionalitäten in einem Test nicht so schlimm. Dann können Sie diein separaten Tests vorweg prüfen.
Ergebnis: Vermeiden Sie, spezielle Zugriffsmethoden für Zustand nur zum Zweck desTestens einzurichten. Allemal, wenn sie sie nicht wirklich isoliert testen können.
Zustandstest durch Ableitung?
Auf Zustand können Sie aber nicht nur von außen zugreifen, einfacher ist es von innen. EineAlternative zu Zugriffsmethoden wäre daher die Ableitung einer Klasse vom SUT. Deren Zustandwäre ja der des Warenkorbs. Dazu müssten Sie nur die Sichtbarkeit des Zustands ändern:
class KataPotterShoppingBasket{
protected
Dictionary<int,int> books =new Dictionary<int,int>();
...}
Eine Ableitung kann dann “gefahrlos” eine Zugriffsmethode anbieten. Die “verunreinigt” dieDomänenklasse nicht:
class TestableShoppingBasket:KataPotterShoppingBasket
{ public intCount {get{return base.books.Count; } }
}
Zustand als Abhängigkeit, 26.12.2009Seite 2
Add a Comment