Modul A
enthält import B
oben. Allerdings unter Testbedingungen würde Ich mag verspotten B
in A
(Mock A.B
) und vollständig verzichten zu importieren B
.
Tatsächlich wird B
es nicht absichtlich in der Testumgebung installiert.
A
ist das zu testende Gerät. Ich muss A
mit all seiner Funktionalität importieren . B
ist das Modul, das ich verspotten muss. Aber wie kann ich verspotten B
innerhalb A
und Stopp A
von der realen importieren B
, wenn das erste , was A
tut Import ist B
?
(Der Grund, warum B nicht installiert ist, ist, dass ich Pypy für schnelle Tests verwende und B leider noch nicht mit Pypy kompatibel ist.)
Wie könnte das gemacht werden?
quelle
Mock
einige magische Attribute (__%s__
) wie nicht gepatcht werden__name__
.sys.modules['B'] = None
aber es scheint nicht zu funktionieren.mock
und dannmock.Mock()
Das eingebaute
__import__
kann für mehr Kontrolle mit der ' Mock' -Bibliothek verspottet werden:Sprich
A
sieht aus wie:A.a()
Rückgaben,b_mock.func()
die auch verspottet werden können.Hinweis für Python 3: Wie im Änderungsprotokoll für 3.0 angegeben ,
__builtin__
heißt es jetztbuiltins
:Der Code in dieser Antwort funktioniert einwandfrei, wenn Sie Python 3
__builtin__
durch ersetzenbuiltins
.quelle
import_mock
ich für das gerufen werdeimport A
, aber nicht für irgendetwas, das es importiert.ImportError: No module named '__builtin__'
__builtin__
__builtin__
durchbuiltins
für Python3 ( docs.python.org/3/whatsnew/3.0.html?highlight=__builtin__ )Einfach, verspotten Sie einfach die Bibliothek in sys.modules, bevor sie importiert wird:
und dann, solange
A
nicht bestimmte Datentypen von Bs Objekten zurückgegeben werden:sollte einfach funktionieren.
Sie können auch verspotten
import A.B
:Dies funktioniert auch, wenn Sie Submodule haben, aber Sie möchten jedes Modul verspotten. Angenommen, Sie haben Folgendes:
Führen Sie zum Verspotten einfach die folgenden Schritte aus, bevor das Modul mit den oben genannten Elementen importiert wird:
(Meine Erfahrung: Ich hatte eine Abhängigkeit, die auf einer Plattform, Windows, funktioniert, aber nicht unter Linux, wo wir unsere täglichen Tests ausführen. Also musste ich die Abhängigkeit für unsere Tests verspotten. Zum Glück war es eine Black Box Ich musste nicht viel Interaktion einrichten.)
Verspottende Nebenwirkungen
Nachtrag: Eigentlich musste ich einen Nebeneffekt simulieren, der einige Zeit in Anspruch nahm. Also brauchte ich die Methode eines Objekts, um eine Sekunde lang zu schlafen. Das würde so funktionieren:
Und dann dauert es einige Zeit, bis der Code ausgeführt wird, genau wie bei der eigentlichen Methode.
quelle
Mir ist klar, dass ich hier etwas zu spät zur Party komme, aber hier ist eine etwas verrückte Möglichkeit, dies mit der
mock
Bibliothek zu automatisieren :(hier ist ein Beispiel für die Verwendung)
Der Grund, warum dies so lächerlich kompliziert ist, ist, wenn Python importiert wird, dass Python dies im Grunde tut (zum Beispiel
from herp.derp import foo
)sys.modules['herp']
? Andernfalls importieren Sie es. Wenn immer noch nichtImportError
sys.modules['herp.derp']
? Andernfalls importieren Sie es. Wenn immer noch nichtImportError
foo
von abrufensys.modules['herp.derp']
. SonstImportError
foo = sys.modules['herp.derp'].foo
Diese gemeinsam gehackte Lösung hat einige Nachteile: Wenn sich etwas anderes auf andere Dinge im Modulpfad stützt, wird diese Art von Fehler behoben. Dies funktioniert auch nur für Dinge, die inline importiert werden, wie z
oder
quelle
Aaron Halls Antwort funktioniert für mich. Ich möchte nur eine wichtige Sache erwähnen:
wenn in
A.py
dirfrom B.C.D import E
dann
test.py
müssen Sie in jedem Modul entlang des Pfades verspotten, sonst bekommen SieImportError
quelle
Ich habe einen guten Weg gefunden, die Importe in Python zu verspotten. Es ist Erics Zaadi- Lösung, die ich hier in meiner Django- Anwendung verwende.
Ich habe eine Klasse,
SeatInterface
die Schnittstelle zurSeat
Modellklasse ist. Also habeseat_interface
ich in meinem Modul einen solchen Import:Ich wollte isolierte Tests für die
SeatInterface
Klasse mit verspotteterSeat
Klasse als erstellenFakeSeat
. Das Problem war - wie man Tests offline ausführt, wenn die Django-Anwendung nicht verfügbar ist. Ich hatte unten Fehler:Die Lösung war:
Und dann läuft der Test magisch OK :)
quelle
Wenn Sie eine machen
import ModuleB
, rufen Sie die eingebaute Methode wirklich auf__import__
als:Sie können diese Methode überschreiben, indem Sie das
__builtin__
Modul importieren und einen Wrapper um die__builtin__.__import__
Methode erstellen . Oder Sie könnten mit demNullImporter
Haken aus demimp
Modul spielen. Fangen Sie die Ausnahme ab und verspotten Sie Ihr Modul / Ihre Klasse in derexcept
Block.Zeiger auf die entsprechenden Dokumente:
docs.python.org:
__import__
Zugriff auf Import-Interna mit dem imp-Modul
Ich hoffe das hilft. Seien Sie sehr darauf hingewiesen, dass Sie in die geheimnisvolleren Grenzen der Python-Programmierung eintreten und dass a) ein solides Verständnis dessen, was Sie wirklich erreichen möchten, und b) ein gründliches Verständnis der Auswirkungen wichtig sind.
quelle