Erweitertes Mocking im Unittest-Framework
Im vorherigen Kapitel haben wir die Bedeutung der Verwendung von Mock beim Testen gesehen. Nun betrachten wir die verschiedenen Möglichkeiten genauer und klären eventuelle Unklarheiten.
Einführung in MagicMock
MagicMock ist eine äußerst vielseitige Implementierung von Mock, die Magische Methoden unterstützt. Damit lässt sich das Verhalten komplexer Objekte in Tests nachbilden, wie bereits im vorherigen Kapitel gezeigt.
from unittest.mock import MagicMock
import unittest
class BankAccount:
def __init__(self, id):
self.id = id
self.balance = self.get_account_balance(id)
def get_account_balance(self, id):
# Simulates a database call
pass
class TestBankAccount(unittest.TestCase):
def test_balance_retrieval(self):
account = BankAccount(1)
account.get_account_balance = MagicMock(return_value=1000)
self.assertEqual(account.balance, 1000)
In diesem Beispiel wird MagicMock verwendet, um die Methode get_account_balance
zu simulieren, die normalerweise Daten aus einer Datenbank abruft.
Verwendung von mock.patch
@mock.patch wird verwendet, um reale Implementierungen von Objekten im Code vorübergehend zu ersetzen.
Stellen Sie sich eine Funktion vor, die Benutzeranmeldedaten gegen eine Datenbank prüft. Mit mock.patch lässt sich vermeiden, dass tatsächlich auf die Datenbank zugegriffen wird:
from unittest.mock import patch
import unittest
def authenticate(username, password):
# Assume this function checks credentials against a database
pass
class TestAuthentication(unittest.TestCase):
@patch('module_containing.authenticate')
def test_login(self, mock_auth):
mock_auth.return_value = True
response = authenticate('user', 'pass')
self.assertTrue(response)
Mocking mit Context Manager
Manchmal ist es sinnvoller, patch() als Context Manager statt als Decorator zu verwenden, insbesondere wenn:
- ein Objekt nur für einen Teil des Tests gemockt werden soll;
- oder wenn zu viele Decorators oder Parameter die Lesbarkeit der Tests beeinträchtigen.
from unittest.mock import patch
import unittest
class BankAccount:
def __init__(self, id):
self.id = id
self.balance = self.get_account_balance(id)
def get_account_balance(self, id):
# Simulates a database call
return 0
class TestBankAccount(unittest.TestCase):
def test_balance_retrieval(self):
with patch.object(BankAccount, 'get_account_balance', return_value=1000) as mock_get:
account = BankAccount(1)
self.assertEqual(account.balance, 1000)
mock_get.assert_called_once_with(1)
Pytest Monkey Patch
Das monkeypatch-Fixture in Pytest ermöglicht es, Klassen, Module oder Umgebungen während eines Tests vorübergehend zu verändern.
import os
import pytest
def test_api_url(monkeypatch):
# Set the API_URL environment variable to a test URL
monkeypatch.setenv('API_URL', 'https://testapi.com')
# Now check that the environment variable was set correctly
assert os.environ['API_URL'] == 'https://testapi.com'
Das monkeypatch-Fixture ermöglicht es, die Umgebung während des Tests sicher zu verändern und zu verwalten, ohne Nebenwirkungen außerhalb des Testbereichs zu verursachen.
1. Welche der folgenden Code-Snippets mockt die Methode get_balance korrekt, sodass sie 500 zurückgibt?
2. Was überprüft der folgende Test?
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Can you explain the difference between Mock and MagicMock?
How does mock.patch work with classes and methods?
When should I use a context manager instead of a decorator for patching?
Awesome!
Completion rate improved to 3.13
Erweitertes Mocking im Unittest-Framework
Swipe um das Menü anzuzeigen
Im vorherigen Kapitel haben wir die Bedeutung der Verwendung von Mock beim Testen gesehen. Nun betrachten wir die verschiedenen Möglichkeiten genauer und klären eventuelle Unklarheiten.
Einführung in MagicMock
MagicMock ist eine äußerst vielseitige Implementierung von Mock, die Magische Methoden unterstützt. Damit lässt sich das Verhalten komplexer Objekte in Tests nachbilden, wie bereits im vorherigen Kapitel gezeigt.
from unittest.mock import MagicMock
import unittest
class BankAccount:
def __init__(self, id):
self.id = id
self.balance = self.get_account_balance(id)
def get_account_balance(self, id):
# Simulates a database call
pass
class TestBankAccount(unittest.TestCase):
def test_balance_retrieval(self):
account = BankAccount(1)
account.get_account_balance = MagicMock(return_value=1000)
self.assertEqual(account.balance, 1000)
In diesem Beispiel wird MagicMock verwendet, um die Methode get_account_balance
zu simulieren, die normalerweise Daten aus einer Datenbank abruft.
Verwendung von mock.patch
@mock.patch wird verwendet, um reale Implementierungen von Objekten im Code vorübergehend zu ersetzen.
Stellen Sie sich eine Funktion vor, die Benutzeranmeldedaten gegen eine Datenbank prüft. Mit mock.patch lässt sich vermeiden, dass tatsächlich auf die Datenbank zugegriffen wird:
from unittest.mock import patch
import unittest
def authenticate(username, password):
# Assume this function checks credentials against a database
pass
class TestAuthentication(unittest.TestCase):
@patch('module_containing.authenticate')
def test_login(self, mock_auth):
mock_auth.return_value = True
response = authenticate('user', 'pass')
self.assertTrue(response)
Mocking mit Context Manager
Manchmal ist es sinnvoller, patch() als Context Manager statt als Decorator zu verwenden, insbesondere wenn:
- ein Objekt nur für einen Teil des Tests gemockt werden soll;
- oder wenn zu viele Decorators oder Parameter die Lesbarkeit der Tests beeinträchtigen.
from unittest.mock import patch
import unittest
class BankAccount:
def __init__(self, id):
self.id = id
self.balance = self.get_account_balance(id)
def get_account_balance(self, id):
# Simulates a database call
return 0
class TestBankAccount(unittest.TestCase):
def test_balance_retrieval(self):
with patch.object(BankAccount, 'get_account_balance', return_value=1000) as mock_get:
account = BankAccount(1)
self.assertEqual(account.balance, 1000)
mock_get.assert_called_once_with(1)
Pytest Monkey Patch
Das monkeypatch-Fixture in Pytest ermöglicht es, Klassen, Module oder Umgebungen während eines Tests vorübergehend zu verändern.
import os
import pytest
def test_api_url(monkeypatch):
# Set the API_URL environment variable to a test URL
monkeypatch.setenv('API_URL', 'https://testapi.com')
# Now check that the environment variable was set correctly
assert os.environ['API_URL'] == 'https://testapi.com'
Das monkeypatch-Fixture ermöglicht es, die Umgebung während des Tests sicher zu verändern und zu verwalten, ohne Nebenwirkungen außerhalb des Testbereichs zu verursachen.
1. Welche der folgenden Code-Snippets mockt die Methode get_balance korrekt, sodass sie 500 zurückgibt?
2. Was überprüft der folgende Test?
Danke für Ihr Feedback!