Hier meine Antwort zur Frage: Wie sollten private Methoden einer Klasse getestet werden?
Hallo Markus,
eine wirklich eindeutige Antwort zu der Frage gibt es allerdings nicht. Wie du schon vermutet hast gibt es viele Entwickler die der Meinung sind, dass private Methoden nicht getestet werden sollten. Der Hintergrund ist, wie von dir richtig angenommen, dass die privaten Methoden durch die Tests der öffentlichen Methoden mit getestet werden.
Einen guten Dankansatz dabei finde ich, dass du Tests gegen die öffentlichen Methoden schreibst um sicher zu stellen, dass sich bei einer Klasse nach aussen nichts ändert bzw. alles richtig funktioniert. Änderst du nun etwas an der Implementierung dieser Klasse, kannst du mithilfe der vorhandenen Tests sicherstellen, dass sich deine Klasse nach aussen immer noch so verhält wie vor der Änderung. Das setzt natürlich voraus, dass du genügend und die richtigen Tests hast.
Die Verwendung von automatischen Unit-Tests haben unheimlich viel mit "gutem" Design zutun. In diesem Fall würde ich sagen die Notwendigkeit eine private Methode zu testen (z.B. weil sie komplex ist oder es schwierig ist ausreichende Tests der verwendenden öffentlichen Methode zu erstellen) ist ein Indiz, dass du Teile deiner Klasse in eine eigene Klasse extrahieren kannst. Es handelt sich hier wie an vielen Stellen um den Ansatz "Single Responsibility Pattern".
Aus der Praxis kann ich allerdings auch sagen, dass es manchmal wirklich schwierig und zeitaufwendig ist alles optimal für Unit-Tests zu entwicklen. Was auch impliziert, dass ich TDD (Test-Drive-Development) selten so einsetze wie es eigentlich gedacht ist. Das ist jedoch ein Thema an dem ich dringend arbeiten muss, weil ich grundsätzlich die Vorteile von TDD schätze und denke, dass es in vielen Projekten wirklich hilfreich ist. Allerdings braucht es dafür einiges an Erfahrung. Auch sollte man hier berücksichtigen wieviel Sinn es für ein konkretes Projekt macht "alles perfekt" zu haben.
Möchtest du nun doch private Methoden testen, dann gibt es (mit Ausnahme von der .NET Core Variante) in Visual Studio Test eine Klasse mit dem Namen PrivateObject. Diese erlaubt es dir via Reflection private Methode einer Klasse zu testen. Microsoft hat sich allerdings in .NET Core entschieden diesen Ansatz nicht weiterzuverfolgen, weil er als "falsch" angesehen wird.
Hier meine Antwort zur Frage: Wie sollten private Methoden einer Klasse getestet werden?
Hallo Markus,
eine wirklich eindeutige Antwort zu der Frage gibt es allerdings nicht. Wie du schon vermutet hast gibt es viele Entwickler die der Meinung sind, dass private Methoden nicht getestet werden sollten. Der Hintergrund ist, wie von dir richtig angenommen, dass die privaten Methoden durch die Tests der öffentlichen Methoden mit getestet werden.
Einen guten Dankansatz dabei finde ich, dass du Tests gegen die öffentlichen Methoden schreibst um sicher zu stellen, dass sich bei einer Klasse nach aussen nichts ändert bzw. alles richtig funktioniert. Änderst du nun etwas an der Implementierung dieser Klasse, kannst du mithilfe der vorhandenen Tests sicherstellen, dass sich deine Klasse nach aussen immer noch so verhält wie vor der Änderung. Das setzt natürlich voraus, dass du genügend und die richtigen Tests hast.
Die Verwendung von automatischen Unit-Tests haben unheimlich viel mit "gutem" Design zutun. In diesem Fall würde ich sagen die Notwendigkeit eine private Methode zu testen (z.B. weil sie komplex ist oder es schwierig ist ausreichende Tests der verwendenden öffentlichen Methode zu erstellen) ist ein Indiz, dass du Teile deiner Klasse in eine eigene Klasse extrahieren kannst. Es handelt sich hier wie an vielen Stellen um den Ansatz "Single Responsibility Pattern".
Aus der Praxis kann ich allerdings auch sagen, dass es manchmal wirklich schwierig und zeitaufwendig ist alles optimal für Unit-Tests zu entwicklen. Was auch impliziert, dass ich TDD (Test-Drive-Development) selten so einsetze wie es eigentlich gedacht ist. Das ist jedoch ein Thema an dem ich dringend arbeiten muss, weil ich grundsätzlich die Vorteile von TDD schätze und denke, dass es in vielen Projekten wirklich hilfreich ist. Allerdings braucht es dafür einiges an Erfahrung. Auch sollte man hier berücksichtigen wieviel Sinn es für ein konkretes Projekt macht "alles perfekt" zu haben.
Möchtest du nun doch private Methoden testen, dann gibt es (mit Ausnahme von der .NET Core Variante) in Visual Studio Test eine Klasse mit dem Namen
PrivateObject
. Diese erlaubt es dir via Reflection private Methode einer Klasse zu testen. Microsoft hat sich allerdings in .NET Core entschieden diesen Ansatz nicht weiterzuverfolgen, weil er als "falsch" angesehen wird.Möchtest du zu diesem Thema ins Detail gehen, dann kann ich dir diesen Artikel zum Thema Testpyramide empfehlen (ist allerdings auf Englisch :-(). Ebenfalls auf Englisch, aber ein wirklich tolles Buch ist XUnit Test Patterns von Gerard Meszaros.
Ich hoffe das konnte etwas Licht ins Dunkel bringen.