Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| modul:m450:learningunits:lu04:monkeypatch [2024/10/02 10:25] – angelegt msuter | modul:m450:learningunits:lu04:monkeypatch [2024/11/12 07:30] (aktuell) – msuter | ||
|---|---|---|---|
| Zeile 7: | Zeile 7: | ||
| Ein Unittest soll eine einzelne Funktion oder sogar nur Teile einer Funktion testen. | Ein Unittest soll eine einzelne Funktion oder sogar nur Teile einer Funktion testen. | ||
| Die zu testende Funktion wird aber in der Regel Objekte verarbeiten und weitere Funktionen/ | Die zu testende Funktion wird aber in der Regel Objekte verarbeiten und weitere Funktionen/ | ||
| - | Dadurch wird es schwieriger | + | Funktionen und Klassen werden bei Unittests simuliert (oder " |
| - | Auch Zugriffe | + | ==== Isolation der Testobjekte ==== |
| + | Mocking hilft, sich nur auf die zu testende Funktion oder Klasse zu konzentrieren, | ||
| + | |||
| + | ==== Vermeidung externer Abhängigkeiten ==== | ||
| + | In vielen Anwendungen greifen Funktionen und Klassen auf externe Ressourcen zu, wie Datenbanken, APIs, Dateisysteme oder Netzwerke. Diese Ressourcen sind oft schwer zugänglich, | ||
| + | |||
| + | ==== Kontrolle | ||
| + | Mocks ermöglichen es, gezielt verschiedene Rückgabewerte oder Fehler zu simulieren, um zu überprüfen, | ||
| + | |||
| + | ==== Verbesserte Performance ==== | ||
| + | Da Mocks die tatsächlichen Ausführungen komplexer | ||
| + | |||
| + | Insgesamt macht Mocking Unittests flexibler, effizienter und zuverlässiger, | ||
| ===== Funktionen simulieren ===== | ===== Funktionen simulieren ===== | ||
| - | Nehmen wir einmal an, wir möchten eine Funktion '' | + | Nehmen wir einmal an, wir möchten eine Funktion '' |
| - | Diese Funktion ruft eine andere Funktion '' | + | Diese Funktion ruft eine andere Funktion '' |
| - | Für unsere Unittests der Funktion '' | + | Für unsere Unittests der Funktion '' |
| <code python> | <code python> | ||
| - | Beispiel mit simulierter | + | # my_module.py |
| + | |||
| + | def get_data_from_database(): | ||
| + | """ | ||
| + | Diese Funktion | ||
| + | Wir simulieren diese Funktion im Test. | ||
| + | """ | ||
| + | # Hier könnte normalerweise eine Datenbankabfrage stehen | ||
| + | raise NotImplementedError(" | ||
| + | |||
| + | def process_data(): | ||
| + | """ | ||
| + | Diese Funktion ruft Daten von der Datenbank ab und verarbeitet sie. | ||
| + | """ | ||
| + | data = get_data_from_database() | ||
| + | # Verarbeiten wir die Daten (hier nur ein einfaches Beispiel) | ||
| + | return [item * 2 for item in data] | ||
| </ | </ | ||
| + | |||
| + | <code python> | ||
| + | import pytest | ||
| + | from my_module import process_data | ||
| + | |||
| + | # Fixture zum Simulieren der Datenbankabfrage-Funktion | ||
| + | @pytest.fixture | ||
| + | def mock_get_data_from_database(monkeypatch): | ||
| + | """ | ||
| + | Simuliert die Funktion `get_data_from_database`, | ||
| + | """ | ||
| + | def mock_data(): | ||
| + | return [1, 2, 3] # Beispielhafte Testdaten, die anstelle echter Daten zurückgegeben werden | ||
| + | |||
| + | # Ersetzen der echten Funktion durch die simulierte Version | ||
| + | monkeypatch.setattr(" | ||
| + | |||
| + | def test_process_data(mock_get_data_from_database): | ||
| + | """ | ||
| + | Testet die Funktion `process_data`, | ||
| + | """ | ||
| + | result = process_data() | ||
| + | assert result == [2, 4, 6], "Die Daten sollten verdoppelt werden." | ||
| + | </ | ||
| + | |||
| + | Mit der Zeile '' | ||
| + | dass anstelle von '' | ||
| ===== Klassen simulieren ===== | ===== Klassen simulieren ===== | ||
| Zeile 27: | Zeile 82: | ||
| <code python> | <code python> | ||
| - | Beispiel mit simulierter | + | # database_module.py |
| + | |||
| + | class DatabaseClient: | ||
| + | """ | ||
| + | | ||
| + | """ | ||
| + | def fetch_data(self): | ||
| + | # In einer echten Anwendung würde hier eine Datenbankabfrage stehen. | ||
| + | raise NotImplementedError(" | ||
| + | |||
| + | def get_processed_data(db_client): | ||
| + | """ | ||
| + | Funktion, die Daten vom DatabaseClient abruft und verarbeitet. | ||
| + | """ | ||
| + | data = db_client.fetch_data() | ||
| + | # Beispielhafte Verarbeitung: | ||
| + | return [item + 1 for item in data] | ||
| </ | </ | ||
| + | <code python> | ||
| + | # test_database_module.py | ||
| + | |||
| + | import pytest | ||
| + | from database_module import get_processed_data | ||
| + | |||
| + | # Fixture zum Simulieren der Klasse DatabaseClient | ||
| + | @pytest.fixture | ||
| + | def mock_db_client(monkeypatch): | ||
| + | """ | ||
| + | Simuliert die DatabaseClient-Klasse, | ||
| + | """ | ||
| + | # Simulierte Klasse | ||
| + | class MockDatabaseClient: | ||
| + | def fetch_data(self): | ||
| + | return [10, 20, 30] # Beispielhafte Testdaten | ||
| + | |||
| + | # Ersetzen der echten DatabaseClient-Klasse durch die simulierte Version | ||
| + | monkeypatch.setattr(" | ||
| + | | ||
| + | # Instanz der simulierten Klasse zurückgeben | ||
| + | return MockDatabaseClient() | ||
| + | |||
| + | def test_get_processed_data(mock_db_client): | ||
| + | """ | ||
| + | Testet die Funktion `get_processed_data`, | ||
| + | """ | ||
| + | result = get_processed_data(mock_db_client) | ||
| + | assert result == [11, 21, 31], "Die Daten sollten um 1 erhöht werden." | ||
| + | </ | ||
| + | |||
| + | ==== Erläuterung ==== | ||
| + | ** Fixture mock_db_client: | ||
| + | |||
| + | Diese Fixture erstellt eine simulierte Version der '' | ||
| + | Mit '' | ||
| + | |||
| + | ** Test test_get_processed_data: | ||
| + | |||
| + | Der Test nutzt die Fixture '' | ||
| + | Da '' | ||