Unit Testen von abstrakten Klassen und / oder Interfaces

8

Ich versuche, Unit Testing für mein aktuelles Projekt in Visual Studio 2010 zu verwenden. Meine Klassenstruktur enthält jedoch eine Reihe von Vererbungsbeziehungen zwischen Interface und abstrakten Klassen.

Wenn zwei Klassen von derselben abstrakten Klasse oder Schnittstelle abgeleitet werden, möchte ich den Testcode zwischen ihnen teilen können. Ich bin mir nicht sicher, wie ich das genau machen soll. Ich denke, ich erstelle eine Testklasse für jede Schnittstelle, die ich testen möchte, aber ich bin mir nicht sicher, wie ich meine konkreten Klassen in die anwendbaren Komponententests einspeisen kann.

Aktualisieren

OK, hier ist ein Beispiel. Angenommen, ich habe eine Schnittstelle IEmployee, die von einer abstrakten Klasse Employee implementiert wird, die dann von den beiden konkreten Klassen Worker und Employee geerbt wird. (Code siehe unten)

Sagen Sie jetzt, ich möchte Tests erstellen, die für alle Mitarbeiter oder Mitarbeiter gelten. Alternativ können Sie spezifische Tests für bestimmte Arten von Mitarbeitern erstellen. Zum Beispiel möchte ich behaupten, dass das Setzen von IEmployee.Number auf eine Zahl kleiner Null für jede Implementierung von IEmployee eine Ausnahme auslöst. Ich würde es vorziehen, die Tests aus der Perspektive eines beliebigen IE-Angestellten zu schreiben und dann die Tests für jede Implementierung von IE-Mitarbeiter verwenden zu können.

Hier ist ein anderes Beispiel. Ich möchte auch behaupten, dass die Urlaubszeit für jeden Mitarbeiter auf einen Wert von weniger als Null wirft und Fehler gesetzt. Vielleicht möchte ich auch andere Tests haben, die für eine bestimmte konkrete Version von Employee gelten. Angenommen, ich möchte testen, dass Worker eine Ausnahme auslöst, wenn sie für mehr als 14 Tage Urlaub bereitgestellt werden, aber ein Manager kann bis zu 36 Tage lang bereitgestellt werden.

%Vor%

Ich denke also, dass ich nach einem Arbeitsablauf suche, der es mir ermöglicht, Komponententests zu verschachteln. Wenn ich zum Beispiel die Manager-Klasse teste, möchte ich zuerst testen, ob sie die Tests Employee und IEmployee besteht und dann bestimmte Mitglieder wie DoSomeManaging() .

testet     
Eric Anastas 16.09.2010, 22:08
quelle

5 Antworten

6

Ich denke ich weiß was du meinst. Ich hatte das gleiche Problem.

Meine Lösung bestand darin, auch zum Testen eine Hierarchie zu erstellen. Ich benutze das gleiche Beispiel, das du zeigst.

Erstens, habe eine abstrakte Testklasse für den Basis-IE-Mitarbeiter.

Es hat zwei Hauptsachen: ich. Alle Testmethoden, die Sie wollen. ii. Eine abstrakte Methode, die die gewünschte Instanz von IEmployee zurückgibt.

%Vor%

Zweitens haben Sie eine Testklasse für jede Implementierung von IEmployee, implementieren die abstrakte Methode und stellen geeignete Instanzen von IEmployee bereit.

%Vor%

Sie können sehen, dass alles wie erwartet funktioniert und VS gibt Ihnen die erwarteten Testmethoden für jede WorkerTests- und ManagerTests-Klasse im TestView-Fenster. Sie können sie ausführen und die Testergebnisse für jede Implementierung der IEmployee-Schnittstelle anzeigen. Sie müssen die Tests nur in der Basisklasse IEmployeeTests erstellen.

Sie können immer einen spezifischen Test für die abgeleiteten Klassen WorkerTests und ManagerTests hinzufügen.

Die Frage wäre jetzt, was ist mit Klassen, die mehrere Schnittstellen implementieren, sagen wir EmployedProgrammer?

%Vor%

Wir haben keine Mehrfachvererbung in C #, daher ist dies keine Option:

%Vor%

Für dieses Szenario besteht eine Lösung darin, die folgenden Testklassen zu verwenden:

%Vor%

mit

%Vor%

Ich benutze das mit guten Ergebnissen. Hoffe es hilft.

Grüße, Jose

    
Jose 27.05.2011 16:46
quelle
0

Ich denke, Sie möchten Unit-Tests für Methoden in abstrakten Klassen erstellen.

Ich bin mir nicht sicher, ob es Sinn macht, eine geschützte Methode für eine abstrakte Klasse zu testen, aber wenn Sie darauf bestehen, die Klasse einfach in einer Klasse zu erweitern, die ausschließlich für Unittests verwendet wird. Auf diese Weise können Sie die geschützten Methoden der abstrakten Klasse, die Sie testen möchten, über öffentliche Methoden für die extending-Klasse verfügbar machen, die einfach die Methode der abstrakten Klasse aufrufen.

Wenn Sie Methoden in abstrakten Klassen haben, die Sie einteilen möchten, empfehle ich, sie in separate Klassen umzuwandeln und sie einfach als öffentliche Methoden verfügbar zu machen und diese zu testen. Versuchen Sie, Ihren Vererbungsbaum aus einer "Test-zuerst" -Perspektive zu betrachten, und ich bin mir ziemlich sicher, dass Sie diese Lösung (oder eine ähnliche) auch finden werden.

    
JDT 16.09.2010 22:27
quelle
0

Es scheint, dass Sie "Composite Unit Testing" beschrieben haben, das von Unit-Tests von Visual Studio 2010 nicht unterstützt wird. Solche Dinge können in MbUnit nach diesem Artikel gemacht werden. Es ist möglich, abstrakte Tests in Visual Studio 2010 zu erstellen, was wahrscheinlich nicht genau Ihren Vorstellungen entspricht. Hier finden Sie eine Beschreibung, wie Sie abstrakte Tests in VS implementieren (Abschnitt Vererbungsbeispiel) ).

    
Jakub Linhart 04.04.2011 21:25
quelle
0

Verwenden Sie Microsoft Mole für bessere Tests. So können Sie die abstrakte Basisklasse / statische Methoden usw. leicht verspotten. Bitte lesen Sie den folgenden Post für weitere Informationen

Umweg-abstrakte-Basis-Klassen-Verwendung-Maulwürfe

%Vor%     
mahesh 29.07.2011 07:35
quelle
0

Der Wunsch, denselben Test für mehrere Klassen auszuführen, bedeutet normalerweise, dass Sie die Möglichkeit haben, das Verhalten, das Sie testen möchten, in eine einzelne Klasse zu extrahieren (sei es die Basisklasse oder eine völlig neue Klasse, die Sie in Ihre vorhandenen Klassen einbauen).

Betrachten Sie Ihr Beispiel: Statt Urlaubsbegrenzungen in Worker und Manager zu implementieren, fügen Sie eine neue Mitgliedsvariable zu Employee , 'MaximumVacationDays' hinzu, implementieren Sie das Limit im Setter der Angestelltenklasse und überprüfen Sie das Limit dort :

%Vor%

Jetzt haben Sie nur eine Methode zum Testen und weniger Code zum Verwalten.

    
Jeff Sternal 10.08.2011 23:59
quelle