*** # Test Doubles *** ### Modul 450 --- ## Abhängigkeiten # Tests mit Abhängigkeiten *** Worin besteht das Problem?

* langsam * aufwändig * schwierig
Note: * zu langsam * Abhängigkeit ruft externen Service auf * Abhängigkeit greift auf Datenbank zu * zu aufwändig * Abhängigkeiten in den richtigen Zustand bringen * zu schwierig * Abhängigkeiten zu bestimmten Verhalten zwingen ---- ## Abhängigkeiten # Veranschaulichung *** Worin liegt hier das Problem?
```mermaid classDiagram namespace Program { class Major { IMinor minor } class Minor } Minor o-- Major ```
Note: * Mit Tests von Major wird Minor mitgetestet ---- ## Abhängigkeiten # Resultat beim Testen ***
```mermaid classDiagram namespace Program { class Major { IMinor minor } class Minor } Minor o-- Major namespace Test { class MajorTest class MinorTest } MajorTest --> Major MinorTest --> Minor ```
* Was testet MajorTest?
Note: * Mit Tests von Major wird Minor mitgetestet ---- ## Abhängigkeiten # Lösung *** Wie kann dies gelöst werden?  Note: * Diskussion in der Reihe (2min) ---- ## Dependency Injection ***
```mermaid classDiagram direction RL namespace Program { class IMinor class Major { IMinor minor Major(minor: IMinor) } class Minor } Minor --|> IMinor IMinor o-- Major namespace Test { class MinorDouble class MajorTest class MinorTest } MinorDouble --|> IMinor MinorDouble <-- MajorTest MajorTest --> Major MinorTest --> Minor ```
Note: * Major erwartet eine Minor-Implementierung als Konstruktorparameter. * Zu Minor wird ein Interface benötigt, das von Minor implementiert wird. * Auch MinorDouble muss dieses Interface implementieren! --- ## Abhängigkeiten # Mocking *** Was macht/ist mocking?  Note: * Das Verhalten von Objekten/Klassen wird mit einer Library definiert. * Was ist bereits bekannt? * Java: Mockito * C#: Moq * Python: unittest.mock * JavaScript: mocha ---- ## Mocking # Frameworks *** * Java: Mockito * C#: Moq * Python: unittest.mock * JavaScript: mocha Note: Die sind nur einige wenige --- ## Abhängigkeiten # Arten von Test Doubles ***
* Dummy * Fake * Stub * Mock * (Spy)

Note: A03-02-testdoubles Gruppenarbeit ~15min Präsentation ~5min ---- ## Test Doubles # Dummy *** * Platzhalter zum übergeben * Irrelevant für den jeweiligen Testfall! Note: * Objekt mit zwei Abhängigkeiten: Cache und Berechnung. * Die Berechnung wird nur verwendet, wenn der Cache den gesuchten Wert nicht enthält. * Für den Cache wird eine funktionierende Implementierung mitgegeben. * Für die Berechnung genügt ein Dummy-Objekt, das nicht verwendet wird. ---- ## Test Doubles # Fake *** * Vereinfachte Implementierung * Datenbank mit ArrayList simulieren * DNS-Lookup mit statischer Map simulieren Note: Eine vereinfachte Implementierung für den jeweiligen Testfall wird bereitgestellt. Beispiele * Eine Datenbank wird mit einer ArrayList simuliert (hinzufügen, entfernen, modifizieren). * Ein DNS-Lookup wird mit einer statischen Map simuliert (nur lesend). ---- ## Test Doubles # Stub *** * Pseudo-Implementierung mit hart-kodierten Antworten * Nahezu keine Programmlogik * Ignoriert Methodenparameter * Immer die gleichen Antworten Note: Eine Pseudo-Implementierung mit hart-kodierten Antworten für den jeweiligen Testfall wird bereitgestellt. Es wird fast keine Programmlogik implementiert. Der Stub ignoriert Methodenparameter und gibt immer die gleichen Antworten. Beispiele: Siehe Fake ---- ## Test Doubles # Mock *** Ausgeklügelter Stub mit “Erinnerungsvermögen” * Liefert ebenfalls hartkodierte Antworten * Merkt sich Aufrufe * Aufrufe können überprüft werden Note: Ein ausgeklügelter Stub mit “Erinnerungsvermögen” wird bereitgestellt. Der Mock liefert ebenfalls hartkodierte Antworten. Er merkt sich jedoch Aufrufe, die dann überprüft werden können. Beispiele Zähler, der sich merkt, wie oft eine Methode aufgerufen worden ist. Ist ein Wert im Cache, darf der Datenbank-Mock nicht aufgerufen werden. Ist ein Wert nicht im Cache, muss der Datenbank-Mock einmal aufgerufen werden. ---- ## Test Doubles # Spy *** * Produktive Implementierung * Von Wrapper umschlossen * Beobachtet das Verhalten des Objektes * Aufrufe werden aufgezeichnet * Testfall bleibt ein Integrationstest! Note: Eine produktive Implementierung einer Abhängigkeit wird von einem Wrapper umschlossen. Der Spy beobachten das Verhalten eines Objekts. Die Aufrufe zum Objekt werden aufgezeichnet (Parameter, Rückgabewerte). Der Testfall bleibt ein Integrationstest, jedoch mit zusätzlichen Prüfungen. Eher “white-box”- als “black-box”-Test. --- # Zusammenfassung *** * Probleme mit Abhängigkeiten * Mocking * Arten von Test Doubles