Wir verwenden Mock seit einiger Zeit für Python.
Jetzt haben wir eine Situation, in der wir eine Funktion verspotten wollen
def foo(self, my_param):
#do something here, assign something to my_result
return my_result
Normalerweise wäre der Weg, dies zu verspotten (vorausgesetzt, foo ist Teil eines Objekts)
self.foo = MagicMock(return_value="mocked!")
Auch wenn ich foo () ein paar Mal aufrufe, kann ich verwenden
self.foo = MagicMock(side_effect=["mocked once", "mocked twice!"])
Jetzt stehe ich vor einer Situation, in der ich einen festen Wert zurückgeben möchte, wenn der Eingabeparameter einen bestimmten Wert hat. Wenn wir also sagen, dass "my_param" gleich "etwas" ist, möchte ich "my_cool_mock" zurückgeben.
Dies scheint auf Mockito für Python verfügbar zu sein
when(dummy).foo("something").thenReturn("my_cool_mock")
Ich habe gesucht, wie ich mit Mock dasselbe erreichen kann, ohne Erfolg?
Irgendwelche Ideen?
python
unit-testing
mocking
mockito
Juan Antonio Gomez Moriano
quelle
quelle
monkeypatch
. Monkeypatch ist eher für "Ersetzen dieser Funktion zum Testen", während Mock das ist, was Sie verwenden, wenn Sie auch die Funktion überprüfenmock_calls
oder Aussagen darüber machen möchten, mit was sie aufgerufen wurde, und so weiter. Es gibt einen Platz für beide, und ich verwende beide oft zu unterschiedlichen Zeiten in einer bestimmten Testdatei.Antworten:
http://www.voidspace.org.uk/python/mock/mock.html#calling
quelle
side effect
ist der genaue Begriff: en.wikipedia.org/wiki/Side_effect_(computer_science)CallableMixin.side_effect
, sondern dass die im Beispiel definierte separate Funktion denselben Namen hat.Wie im Python Mock-Objekt angegeben, wird die Methode mehrmals aufgerufen
Eine Lösung besteht darin, meinen eigenen Nebeneffekt zu schreiben
Das macht den Trick
quelle
Der Nebeneffekt hat eine Funktion (die auch eine Lambda-Funktion sein kann ). In einfachen Fällen können Sie also Folgendes verwenden:
quelle
Ich bin hier gelandet und habe nach " wie man eine Funktion basierend auf Eingabeargumenten verspottet " gesucht und habe dies schließlich gelöst, indem ich eine einfache Hilfsfunktion erstellt habe:
Jetzt:
Hoffe das hilft jemandem!
quelle
Sie können auch
partial
von verwenden,functools
wenn Sie eine Funktion verwenden möchten, die Parameter akzeptiert, die von Ihnen verspottete Funktion jedoch nicht. ZB so:Dies gibt einen Aufruf zurück, der keine Parameter akzeptiert (wie Djangos timezone.now ()), aber meine mock_year-Funktion.
quelle
got multiple values for argument
.Nur um einen anderen Weg zu zeigen:
quelle
Sie können auch verwenden
@mock.patch.object
:Nehmen wir an, ein Modul
my_module.py
verwendetpandas
aus einer Datenbank zu lesen und wir möchten dieses Modul testen , indem spöttischpd.read_sql_table
Methode (die nimmttable_name
als Argument).Sie können (innerhalb Ihres Tests) eine
db_mock
Methode erstellen , die abhängig vom angegebenen Argument unterschiedliche Objekte zurückgibt:In Ihrer Testfunktion tun Sie dann:
quelle
Wenn Sie "einen festen Wert zurückgeben möchten, wenn der Eingabeparameter einen bestimmten Wert hat" , benötigen Sie möglicherweise nicht einmal einen Mock und können einen
dict
zusammen mit seinerget
Methode verwenden:Dies funktioniert gut, wenn die Ausgabe Ihrer Fälschung eine Zuordnung der Eingabe ist. Wenn es sich um eine Funktion der Eingabe handelt, würde ich vorschlagen, sie
side_effect
gemäß der Antwort von Amber zu verwenden .Sie können auch eine Kombination aus beidem verwenden , wenn Sie erhalten wollen
Mock
‚s - Fähigkeiten (assert_called_once
,call_count
usw.):quelle
Ich weiß, es ist eine ziemlich alte Frage, könnte als Verbesserung mit Python Lamdba helfen
quelle