2014-11-20 10 views
9

Aus der Dokumentation http://www.voidspace.org.uk/python/mock/patch.htmlPython Mock Patch Argument `new` vs` new_callable`

patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs) 

Wenn neue weggelassen wird, dann wird das Ziel mit einem MagicMock ersetzt. Wenn patch als Dekorator verwendet wird und new weggelassen wird, wird der erzeugte Schein als zusätzliches Argument an die dekorierte Funktion übergeben. Wenn Patch als Kontextmanager verwendet wird, wird der erstellte Schein vom Kontextmanager zurückgegeben.

new_callable können Sie eine andere Klasse angeben, oder aufrufbar Objekt, das aufgerufen wird, um das neue Objekt zu erstellen. Standardmäßig wird MagicMock verwendet.

Ich versuche, die Unterschiede zwischen den beiden zu verstehen, und welche Situation new_callable statt new

Antwort

15

new ist ein tatsächliches Objekt; new_callable ist ein Aufruf zum Erstellen eines Objekts. Die beiden können nicht zusammen verwendet werden (Sie geben entweder die Ersetzung oder eine Funktion zum Erstellen der Ersetzung an; es ist ein Fehler, beide zu verwenden.)

>>> foo = 6 
>>> with mock.patch('__main__.foo', new=7): 
... print foo 
... 
7 
>>> with mock.patch('__main__.foo', new_callable=lambda : 8): 
... print foo 
... 
8 

Wenn newmock.DEFAULT ist, ist das Objekt ein mock MagicMock Beispiel, gerade weil der Standardwert von new_callableMagicMock ist.

4

[EDIT] In dieser Antwort zu verwenden vermisste ich das Wichtigste, dass new ein Objekt nehmen und new_callable eine aufrufbar (die Fabrik) wie von @chepner richtig gesagt. Ich entferne es nicht, weil es entweder nützliche Notizen enthält.

Durch den Code https://code.google.com/p/mock/source/browse/mock.py#1266 Graben ist klar, dass durch new Sie nicht die Attribute von nominal Argumente festlegen und verwenden spec oder spec_set weil sie eine TypeError Ausnahme ausgelöst.

new_callable kann eine Unterklasse von NonCallableMock selbst sein und Sie können alle Mock-Funktionen in Patch-Definition verwenden.

Sicher ist dieses Verhalten wirklich nicht dokumentiert und auch in http://www.voidspace.org.uk/python/mock/changelog.html#version-0-8-0 können Sie nicht viel mehr als finden.

New new_callable Argument patchen und patch.object so dass Sie Pass in einer Klasse oder kündbare Objekt (statt MagicMock), die das Objekt aufgerufen wird, zu ersetzen, wird

gepatcht Sie

Wie dem auch sei kann nicht so etwas benutzen Sieeine YourMockSubclass, die haben die myobject Unterschrift

@patch("mymodule.myobject", new=YourMockSubclass(), spec=myobject) 

aber in diesem Fall erstellen verwenden müssen:

@patch("mymodule.myobject", new_callable=YourMockSubclass, spec=myobject) 

So haben Sie new_callable jedes Mal wenn Sie für Ihren Mock einen nicht-MagicMock Mock verwenden müssen.

IMHO die einzige nützliche Verwendung ist Spott Eigenschaft.