Читать книгу Dojos für Entwickler - Stefan Lieser - Страница 15
Funktionseinheiten identifizieren
ОглавлениеDie erste Aufgabe ist also das Ermitteln der zu testenden Properties. Eingangsparameter in diese Funktionseinheit ist der Typ, für den die INotifyPropertyChanged-Implementierung überprüft werden soll. Das Ergebnis der Flowstage ist eine Aufzählung der Property-Namen.
static IEnumerable<string>
FindPropertyNames(this Type type)
An dieser Stelle fragen Sie sich möglicherweise, warum ich die Property-Namen als Strings zurückgebe und nicht etwa eine Liste von PropertyInfo-Objekten. Schließlich stecken in PropertyInfo mehr Informationen, insbesondere der Typ der Property, den ich später ebenfalls benötige. Ich habe mich dagegen entschieden, weil dies das Testen der nächsten Flowstage deutlich erschwert hätte. Denn diese hätte dann auf einer Liste von PropertyInfo-Objekten arbeiten müssen. Und da PropertyInfo-Instanzen nicht einfach mit new hergestellt werden können, wären die Tests recht mühsam geworden.
Nachdem die Property-Namen bekannt sind, kann die nächste Flowstage dazu den jeweiligen Typ ermitteln. Die Flowstage erhält also eine Liste von Property-Namen sowie den Typ und liefert eine Aufzählung von Typen.
static IEnumerable<Type> FindPropertyTypes(
this IEnumerable<string> propertyNames,
Type type)
Im Anschluss muss für jeden Typ ein Objekt instanziert werden. Diese Objekte werden später im Test den Properties zugewiesen. Die Flowstage erhält also eine Liste von Typen und liefert für jeden dieser Typen eine Instanz des entsprechenden Typs.
static IEnumerable<object> GenerateValues(
this IEnumerable<Type> types)
Dann wird es spannend: Die Actions müssen erzeugt werden. Dabei lässt es sich leider nicht vermeiden, die Property-Namen aus der ersten Stage nochmals zu verwenden. Die Ergebnisse der ersten Stage fließen also nicht nur in die unmittelbar nächste Stage, sondern zusätzlich auch noch in die Stage, welche die Actions erzeugt. Die Namen der Properties werden benötigt, um mittels Reflection die jeweiligen Setter aufrufen zu können.
static IEnumerable<Action<object>>
GenerateTestMethods(this IEnumerable<object>
values, IEnumerable<string> propertyNames,
Type type)
Der letzte Schritt besteht darin, die gelieferten Actions auszuführen. Dazu muss jeweils eine Instanz der zu testenden Klasse erzeugt und an die Action übergeben werden.
Abbildung 2 zeigt den gesamten Flow. Die einzelnen Flowstages sind als Extension Method implementiert. Der Flow selbst wird in der öffentlichen Methode Notifica-tionTester.Verify zusammengesteckt. Testen möchte ich die einzelnen Stages aber isoliert. Denn nur so kann ich die Implementierung Schritt für Schritt vorantreiben und muss nicht gleich einen Integrationstest für den gesamten Flow schreiben. Einige Integrationstests sollten am Ende aber auch nicht fehlen.
Diese Vorgehensweise hat einen weiteren Vorteil: Um den NotificationTester testen zu können, müssen Testdaten her. Da er auf Typen arbeitet, müssen also Testdaten in Form von Klassen erstellt werden. Das ist nicht nur aufwendig, sondern wird auch schnell unübersichtlich. Ganz kommt man zwar am Erstellen solcher Testklassen auch nicht vorbei, aber der Aufwand ist doch reduziert.
[Abb. 2] Die zu testenden Properties ermitteln.