In letzter Zeit musste ich Unit-Tests mit Pytest für ein Python-Modul schreiben. Das Modul enthält eine Klasse, in deren Konstruktor andere Klassen initialisiert werden.
Wie üblich habe ich eine Vorrichtung für diese Klasse erstellt, um das Schreiben eines Tests für jede Klassenmethode zu vereinfachen. Zu diesem Zeitpunkt stieß ich auf einige Probleme, als ich versuchte, die verschiedenen im Konstruktor initiierten Klassen zu verspotten. Das Verspotten hat nicht funktioniert und es wurden immer noch Instanzen dieser Klassen erstellt.
Nach einigen Recherchen und der Kombination einiger verschiedener Lösungen, die ich online gefunden habe, möchte ich mitteilen, wie ich es geschafft habe, die Kurse nachzuahmen.
Hier ist ein Beispiel der Klasse, die ich zu verspotten versuchte:
class ClassA: def __init__(self): self.class_b = ClassB() self.class_c = ClassC() self.count = 0
Wir möchten bei Tests für jedes Feld dieser Klasse einen Wert festlegen. Dieser Wert kann None oder ein Klassenmock sein, aber wir wollen keine Initiationen der Klassen ClassB und ClassC.
In unserem Fall entscheiden wir, dass self.class_b und self.class_c Mocks sein sollten:
@pytest.fixture def mock_class_b(): class_b = Mock(spec=ClassB) return class_b @pytest.fixture def mock_class_c(): class_c = Mock(spec=ClassC) return class_c
Ein Spielplan für diesen Kurs, der unserem Ziel dient, sieht also so aus:
@pytest.fixture def class_a_mock(mock_class_b, mock_class_c): with patch.object(target=ClassA, attribute="__init__", return_value=None) as mock_init: class_a = ClassA() class_a.class_b = mock_class_b class_a.class_c = mock_class_c class_b.count = 0 return class_a
Der wichtige Teil ist die Verwendung der Funktion patch.object, die aus dem Modul unittest.mock in Python stammt. Es wird beim Testen verwendet, um ein Attribut eines bestimmten Objekts vorübergehend durch einen Schein oder einen anderen Wert zu ersetzen.
Argumente
Auf diese Weise können wir simulierte Variablen in unserem Fixture erstellen.
Lesen Sie mehr über patch.object
Ich habe dieses Tutorial für solche Fälle geschrieben, in denen wir den Code der Klasse A aus irgendeinem Grund nicht ändern können. Ich empfehle jedoch generell, den Code nach Möglichkeit zu ändern, nicht um die Logik zu ändern, sondern um ihn testbarer zu machen .
Hier sind einige Beispiele, wie man Klasse A ändern kann, um sie testbarer zu machen:
Option 1:Übergeben Sie Instanzen der Klassen B und C als Parameter.
Auf diese Weise können wir beim Schreiben des Fixtures Mocks anstelle von Instanzen übergeben.
class ClassA: def __init__(self, class_b_instance, class_c_instance): self.class_b = class_b_instance self.class_c = class_c_instance self.count = 0
Option 2: Erstellen Sie eine boolesche Variable, die den Testmodus angibt.
Auf diese Weise können wir entscheiden, welche Felder der Klasse A bei ihrer Initiierung einen Wert erhalten oder nicht.
class ClassA: def __init__(self, test_mode=False): if not test_mode: self.class_b = ClassB() self.class_c = ClassC() self.count = 0
Option 3:Erstellen Sie Klasseneinleitungen in einer separaten Methode.
Dieser Ansatz gibt uns die Möglichkeit, den Aufruf von set_class_variables im Testmodul zu vermeiden.
class ClassA: def __init__(self): self.class_b = None self.class_c = None self.count = None def set_class_variables(self): self.class_b = ClassB() self.class_c = ClassC() self.count = 0
Ich hoffe, das hilft! :)
Das obige ist der detaillierte Inhalt vonVerspottung von Python-Klassen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!