Was bedeutet Mocking
Mocking bedeutet in Englisch eine Nachbildung oder Imitation von etwas zu machen.
Wir verwenden Mocking bei Unit-Tests. Ein Objekt, das Sie testen möchten, kann Abhängigkeiten von anderen komplexen Objekten haben. Um das Verhalten des Objekts, das Sie testen möchten, zu isolieren, ersetzen Sie die anderen Objekte durch Mocks, die das Verhalten der realen Objekte simulieren. Mit einfachen Worten ausgedrückt bedeutet Nachahmung also, Objekte zu erstellen, die das Verhalten realer Objekte simulieren.
Beim Unit Testing wollen wir Methoden (siehe Methoden Seminar) einer Klasse isoliert testen. Aber Klassen sind nicht isoliert. Sie verwenden Dienste und Methoden aus anderen Klassen. In dieser Situation mocken wir also die Dienste und Methoden aus anderen Klassen und simulieren ihr reales Verhalten mit Hilfe einiger mocking frameworks und verwenden diese mockten Methoden und Dienste, um isolierte Einzeltests durchzuführen. An dieser Stelle kommen Mocking-Frameworks ins Spiel.
Es gibt eine Vielzahl von Frameworks, die für das Mocking in Unit-Tests verwendet werden, wie PowerMock, Mockito, EasyMock usw.
Allgemeine Arten von Mocking-Frameworks sind:
Fakes: Ein Fake ist ein Objekt, das den eigentlichen Code ersetzt, indem es die gleiche Schnittstelle implementiert, ohne jedoch mit anderen Objekten zu interagieren. Gewöhnlich ist der Fake fest codiert, um feste Ergebnisse zurückzugeben. Um auf verschiedene Anwendungsfälle zu testen, müssen viele Fakes eingeführt werden. Das durch die Verwendung von Fakes eingeführte Problem besteht darin, dass, wenn eine Schnittstelle geändert wurde, alle Fakes, die diese Schnittstelle implementieren, ebenfalls geändert werden sollten.
Stubs: Ein Stub ist ein Objekt, das ein bestimmtes Ergebnis auf der Grundlage eines bestimmten Satzes von Eingaben zurückgibt und normalerweise auf nichts reagiert, was außerhalb dessen liegt, was für den Test programmiert wurde. Mit JustMock können Sie einen Stub in einem Test mit einer minimalen Menge an Code erstellen und damit deutlich machen, wie die Abhängigkeit reagieren wird und wie sich das getestete System verhalten soll.
Mocks: Ein Mock ist eine viel ausgefeiltere Version eines Stub. Es wird immer noch Werte wie ein Stub zurückgeben, aber es kann auch mit Erwartungen programmiert werden, wie oft jede Methode in welcher Reihenfolge und mit welchen Daten aufgerufen werden soll. Mit JustMock können Sie einen Mock mit nur einer Zeile Code erstellen, was den Test verständlicher macht.
Mocking-Frameworks werden verwendet, um Ersatzobjekte wie Stubs und Mocks zu erzeugen. Mocking-Frameworks ergänzen Unit-Test-Frameworks, indem sie Abhängigkeiten isolieren, sind aber kein Ersatz für Unit-Test-Frameworks. Indem sie die Abhängigkeiten isolieren, helfen sie dem Unit-Testprozess und unterstützen die Entwickler beim Schreiben zielgerichteterer und präziserer Unit-Tests. Die Tests sind auch schneller, da das zu testende System wirklich isoliert wird.
Wenn das Unit-Test-Rahmenwerk Einrichtungen zum Erstellen von Unit-Tests hinzufügt, müssen die Tests noch ausgeführt werden, um das Verhalten des zu testenden Systems zu verifizieren. Test Runners führen Unit-Tests aus. Die meisten Unit-Test-Rahmenwerke enthalten Testläufer, und sie variieren von einfachen Befehlszeilenläufern bis hin zu grafischen Oberflächen.
Einige Tools, wie z.B. ein Visual Studio-Entwicklerproduktivitätstool, sind in der Lage, viele Arten von Unit-Tests auszuführen.
Code first ist die beliebteste und am weitesten verbreitete Methode. Sie bedeutet, dass zuerst der Code geschrieben wird und danach ein Test geschrieben wird, der die Funktionalität des Codes sicherstellt. Sogar Entwickler, die normalerweise andere Methoden anwenden, verwenden manchmal diese Methode, wenn sie einfache, einmalige Anwendungen schreiben.
Zuerst testen - Testgetriebene Entwicklung (TDD)
Die Test-Erst-Methodik beinhaltet das Schreiben des Unit-Tests vor dem Schreiben des eigentlichen Codes. Dieser Prozess zwingt den Entwickler, über die Schnittstelle der Einheit und die erwarteten Ergebnisse nachzudenken. Ob der Code korrekt geschrieben ist oder nicht, ist bei Anwendung dieser Methodik sofort ersichtlich.
Die testgetriebene Entwicklung basiert auf der "Test first"-Methode, jedoch mit der Einführung des Refactoring (mehr Infos Refactoring Training) . TDD hat den folgenden vorgeschriebenen Satz von Schritten:
Da TDD erfordert, dass jeder Code-Einheit ein Test vorausgeht, der ihre Funktionalität beschreibt, bedeutet die Verwendung dieser Methodik, dem YAGNI-Prinzip (You Are not Going to Need It) zu folgen oder sicherzustellen, dass jede hinzugefügte Funktionalität auch wirklich benötigt wird.
Verhaltensgesteuerte Entwicklung (BDD)
Die verhaltensorientierte Entwicklung basiert auf TDD, aber sie befasst sich auch mit einigen der Fragen, die sich bei der Verwendung von TDD stellen - wo man anfangen soll, was man testen soll, wie viel man in einem Zyklus testen soll und was man in den Tests aufrufen soll. BDD (mehr dazu BDD Seminar) konzentriert sich auf die Verhaltensanforderungen der getesteten Einheiten.
BDD verwendet eine allgegenwärtige Sprache, um die Kommunikation (siehe auch Kommunikation Seminare) zwischen Entwicklern und Interessengruppen zu erleichtern.
Im Folgenden werden die Möglichkeiten beschrieben, wie BDD den Testprozess der Einheiten modifiziert:
Wir verwenden Mocking bei Unit-Tests. Ein Objekt, das Sie testen möchten, kann Abhängigkeiten von anderen komplexen Objekten haben. Um das Verhalten des Objekts, das Sie testen möchten, zu isolieren, ersetzen Sie die anderen Objekte durch Mocks, die das Verhalten der realen Objekte simulieren. Mit einfachen Worten ausgedrückt bedeutet Nachahmung also, Objekte zu erstellen, die das Verhalten realer Objekte simulieren.
Beim Unit Testing wollen wir Methoden (siehe Methoden Seminar) einer Klasse isoliert testen. Aber Klassen sind nicht isoliert. Sie verwenden Dienste und Methoden aus anderen Klassen. In dieser Situation mocken wir also die Dienste und Methoden aus anderen Klassen und simulieren ihr reales Verhalten mit Hilfe einiger mocking frameworks und verwenden diese mockten Methoden und Dienste, um isolierte Einzeltests durchzuführen. An dieser Stelle kommen Mocking-Frameworks ins Spiel.
Es gibt eine Vielzahl von Frameworks, die für das Mocking in Unit-Tests verwendet werden, wie PowerMock, Mockito, EasyMock usw.
Allgemeine Arten von Mocking-Frameworks sind:
- Proxy-basiert (z.B.: EasyMock, JMock, Mockito)
- Bytecode-Manipulation / Classloader-Remapping (z.B.: jMockit, PowerMock)
Fakes: Ein Fake ist ein Objekt, das den eigentlichen Code ersetzt, indem es die gleiche Schnittstelle implementiert, ohne jedoch mit anderen Objekten zu interagieren. Gewöhnlich ist der Fake fest codiert, um feste Ergebnisse zurückzugeben. Um auf verschiedene Anwendungsfälle zu testen, müssen viele Fakes eingeführt werden. Das durch die Verwendung von Fakes eingeführte Problem besteht darin, dass, wenn eine Schnittstelle geändert wurde, alle Fakes, die diese Schnittstelle implementieren, ebenfalls geändert werden sollten.
Stubs: Ein Stub ist ein Objekt, das ein bestimmtes Ergebnis auf der Grundlage eines bestimmten Satzes von Eingaben zurückgibt und normalerweise auf nichts reagiert, was außerhalb dessen liegt, was für den Test programmiert wurde. Mit JustMock können Sie einen Stub in einem Test mit einer minimalen Menge an Code erstellen und damit deutlich machen, wie die Abhängigkeit reagieren wird und wie sich das getestete System verhalten soll.
Mocks: Ein Mock ist eine viel ausgefeiltere Version eines Stub. Es wird immer noch Werte wie ein Stub zurückgeben, aber es kann auch mit Erwartungen programmiert werden, wie oft jede Methode in welcher Reihenfolge und mit welchen Daten aufgerufen werden soll. Mit JustMock können Sie einen Mock mit nur einer Zeile Code erstellen, was den Test verständlicher macht.
Mocking-Frameworks werden verwendet, um Ersatzobjekte wie Stubs und Mocks zu erzeugen. Mocking-Frameworks ergänzen Unit-Test-Frameworks, indem sie Abhängigkeiten isolieren, sind aber kein Ersatz für Unit-Test-Frameworks. Indem sie die Abhängigkeiten isolieren, helfen sie dem Unit-Testprozess und unterstützen die Entwickler beim Schreiben zielgerichteterer und präziserer Unit-Tests. Die Tests sind auch schneller, da das zu testende System wirklich isoliert wird.
Wenn das Unit-Test-Rahmenwerk Einrichtungen zum Erstellen von Unit-Tests hinzufügt, müssen die Tests noch ausgeführt werden, um das Verhalten des zu testenden Systems zu verifizieren. Test Runners führen Unit-Tests aus. Die meisten Unit-Test-Rahmenwerke enthalten Testläufer, und sie variieren von einfachen Befehlszeilenläufern bis hin zu grafischen Oberflächen.
Einige Tools, wie z.B. ein Visual Studio-Entwicklerproduktivitätstool, sind in der Lage, viele Arten von Unit-Tests auszuführen.
Code first ist die beliebteste und am weitesten verbreitete Methode. Sie bedeutet, dass zuerst der Code geschrieben wird und danach ein Test geschrieben wird, der die Funktionalität des Codes sicherstellt. Sogar Entwickler, die normalerweise andere Methoden anwenden, verwenden manchmal diese Methode, wenn sie einfache, einmalige Anwendungen schreiben.
Zuerst testen - Testgetriebene Entwicklung (TDD)
Die Test-Erst-Methodik beinhaltet das Schreiben des Unit-Tests vor dem Schreiben des eigentlichen Codes. Dieser Prozess zwingt den Entwickler, über die Schnittstelle der Einheit und die erwarteten Ergebnisse nachzudenken. Ob der Code korrekt geschrieben ist oder nicht, ist bei Anwendung dieser Methodik sofort ersichtlich.
Die testgetriebene Entwicklung basiert auf der "Test first"-Methode, jedoch mit der Einführung des Refactoring (mehr Infos Refactoring Training) . TDD hat den folgenden vorgeschriebenen Satz von Schritten:
- Schreiben eines automatisierten Unit-Tests, der für die neu zu implementierende Funktionalität zunächst fehlschlägt. Verwendung von Mock-Objekten als Ersatz für Abhängigkeiten.
- Schreiben Sie den Mindestcode, der zum Bestehen des Tests erforderlich ist. Der Code muss nicht perfekt sein, er wird später verfeinert.
- Refactoring (oder Bereinigung) des Codes oder Hinzufügen zusätzlicher Benutzerfälle zum Test
- Stellen Sie sicher, dass die Tests immer noch bestanden werden.
- Wiederholen Sie
Da TDD erfordert, dass jeder Code-Einheit ein Test vorausgeht, der ihre Funktionalität beschreibt, bedeutet die Verwendung dieser Methodik, dem YAGNI-Prinzip (You Are not Going to Need It) zu folgen oder sicherzustellen, dass jede hinzugefügte Funktionalität auch wirklich benötigt wird.
Verhaltensgesteuerte Entwicklung (BDD)
Die verhaltensorientierte Entwicklung basiert auf TDD, aber sie befasst sich auch mit einigen der Fragen, die sich bei der Verwendung von TDD stellen - wo man anfangen soll, was man testen soll, wie viel man in einem Zyklus testen soll und was man in den Tests aufrufen soll. BDD (mehr dazu BDD Seminar) konzentriert sich auf die Verhaltensanforderungen der getesteten Einheiten.
BDD verwendet eine allgegenwärtige Sprache, um die Kommunikation (siehe auch Kommunikation Seminare) zwischen Entwicklern und Interessengruppen zu erleichtern.
Im Folgenden werden die Möglichkeiten beschrieben, wie BDD den Testprozess der Einheiten modifiziert:
- Verwendung automatisierter Tests für Feedback und Regressionstests.
- Verwendung von 'wann' zur Beschreibung einer zu testenden Aktion.
- Verwendung von "sollte", um das vom Code erwartete Verhalten zu beschreiben.
- Mit "sicherstellen", um Verantwortlichkeiten außerhalb des Geltungsbereichs des Codes zu beschreiben.