Angenommen, es gibt zwei Pakete in einem Projekt: some_package
und another_package
.
Ich möchte another_package.function.call_bar
mocking out some_package.foo.bar
testen, da es einige Netzwerk-I / O gibt, die ich vermeiden möchte.
Hier ist ein Test:
%Vor% Zu meiner Überraschung gibt es hello
statt mock
aus. Ich habe versucht, diese Sache zu debuggen, die ipdb Haltepunkt im Test setzt. Wenn ich some_package.foo.bar
nach dem Haltepunkt manuell importiere und bar()
anrufe, bekomme ich patched
.
Bei meinem realen Projekt ist die Situation noch interessanter. Wenn ich pytest im Projektstamm aufruft, wird meine Funktion nicht gepatcht, aber wenn ich tests/test_bar.py
als Argument festlege - funktioniert es.
Soweit ich es verstehe, hat das etwas mit der from some_package.foo import bar
Aussage zu tun. Wenn es ausgeführt wird, bevor Monkeypatching stattfindet, schlägt das Patchen fehl. Aber auf dem verdichteten Testaufbau aus dem obigen Beispiel funktioniert das Patchen nicht in beiden Fällen.
Und warum funktioniert es in IPDB REPL nach dem Treffen eines Haltepunktes?
benannter Import erstellt einen neuen Namen für das Objekt, wenn Sie dann den alten Namen für das Objekt ersetzen, der neue Name ist nicht betroffen
Importieren Sie das Modul und verwenden Sie stattdessen module.bar, das immer das aktuelle Objekt
verwendetbearbeiten:
%Vor%Während Ronnys Antwort funktioniert, müssen Sie den Anwendungscode ändern. Im Allgemeinen sollten Sie dies nicht für Tests tun.
Stattdessen können Sie das Objekt im zweiten Paket explizit patchen. Dies wird in den Dokumenten für das Unittest-Modul erwähnt.
> %Vor%Tags und Links python unit-testing py.test