Ich benutze unittest.mock
, diese wunderbare Bibliothek. Ich war jedoch überrascht von einem unerwarteten Verhalten, und ich sehe keine offensichtliche Lösung. Ich benutze es für meine Komponententests und es ist wichtig zu verstehen, wie es sich verhält, um nützliche Tests zu haben.Wie testet man, ob die Methode der Instanz beim Spotten mit "self" aufgerufen wird?
Ich weiß, der Code unten in show_bar
ist kaputt, es ruft eine Klassenmethode anstelle der Instanzmethode. Doch alle meine mock
Unittests sind vorbei:
-Code einen Fehler enthält,:
class Foo(object):
def bar(self):
return "bar"
def show_bar(self):
return Foo.bar()
Erwartete Nutzung:
foo = Foo()
assert foo.show_bar() == "bar"
# => throw exception: bar() missing 1 required positional argument: 'self'
Unittest erfolglos versucht, diesen Fehler zu fangen mock
:
from unittest.mock import patch
with patch.object(Foo, 'bar', return_value="bar") as mock:
foo = Foo()
assert foo.show_bar() == "bar"
mock.assert_called_once()
# => no errors
Im Idealfall würde Ich mag zu behaupten dass bar
mit self.bar()
genannt und nicht Foo.bar()
; was falsch ist. Leider berücksichtigt die Verwendung von mock.assert_called_with()
nicht die self
noch cls
Parameter, also bin ich ein bisschen verwirrt.
BEARBEITEN: Versuchen zu klären. Ich suche nach Best Practices, um die Bibliothek unittest.mock
zu verwenden, wenn wir die Methode eines Objekts patchen müssen. Es scheint mir nicht klar zu sein, wie man es patcht, derzeit habe ich keine Möglichkeit zu behaupten, wenn es self.bar
oder Foo.bar
ruft.
nichts spotten Sie, rufen Sie einfach 'f = Foo(); f.bar() 'in deinem Testcode. Bei der fehlerhaften Implementierung wird ein 'TypeError' ausgelöst, der den Test fehlschlagen lässt. –
Auch und FWIW, das hat nichts mit 'classmethod' zu tun - in Ihrem Beispiel ist' Foo.bar' eine ungebundene Instanzmethode. –
Entschuldigung, der Code ist zu stark vereinfacht und ich * brauche * zu verwenden, da der tatsächliche Code der Methode nicht aufrufbar ist, ohne seinen Rückgabewert zu verspotten. Wenn "show_bar" den Entwickler 'Foo.bar()' aufruft, nahm ich an, dass 'Foo.bar' entweder eine Klassenmethode oder eine statische Methode ist. Es scheint eine vernünftige Aussage zu sein? – Doomsday