Ein Dingus ist wie ein Scheinobjekt. Der Hauptunterschied besteht darin, dass Sie nicht im Voraus Erwartungen einrichten. Sie führen einfach Ihren Code aus und verwenden einen Dingus anstelle eines anderen Objekts oder einer anderen Klasse, und er erfasst, was damit passiert. Sobald Ihr Code ausgeübt wurde, können Sie Behauptungen darüber vornehmen, was er dem Dingus angetan hat.
Ein neuer Dingus wird aus der Dingus -Klasse erstellt. Sie können Dingus Namen geben, was beim Debuggen Ihrer Tests hilft, insbesondere wenn mehrere Dingus im Spiel sind.
>>> from dingus import Dingus >>> d = Dingus( ' root ' ) >>> d <Dingus root>
Durch den Zugriff auf ein Attribut eines Dingus wird ein neuer Dingus zurückgegeben.
>>> d.something <Dingus root.something>
Es gibt einige Ausnahmen für spezielle Dingus -Methoden. Wir werden einige ein bisschen sehen.
Ein Dingus kann auch wie eine Funktion oder Methode bezeichnet werden. Es ist es egal, wie viele Argumente Sie ihm geben oder welche Argumente sind. Aufrufe eines Dingus geben unabhängig von den Argumenten immer dasselbe Objekt zurück.
>>> d() <Dingus root()> >>> d( ' argument ' ) <Dingus root()> >>> d( 55 ) <Dingus root()>
Wir können jederzeit eine Liste von Anrufen erhalten, die an einen Dingus getätigt wurden. Jeder Eintrag in der Anrufliste enthält:
Hier finden Sie eine Liste der Anrufe, die wir bisher an D getätigt haben:
>>> from pprint import pprint >>> pprint(d.calls) [('()', (), {}, <Dingus root()>), ('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
Sie können Anrufe mit Namen, Argumenten und Keyword -Argumenten filtern:
>>> pprint(d.calls( ' () ' , 55 )) [('()', (55,), {}, <Dingus root()>)]
Wenn Sie sich nicht um den Wert eines bestimmten Arguments kümmern, können Sie beim Filterung den Wert verwenden, der nicht basiert:
>>> from dingus import DontCare >>> pprint(d.calls( ' () ' , DontCare)) [('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
Dingus können mehr als nur auf Attribute zugreifen und aufgerufen werden. Sie unterstützen viele Python -Betreiber. Ziel ist es, jede Interaktion zuzulassen und aufzunehmen:
>>> d = Dingus( ' root ' ) >>> ( 2 ** d.something)[ ' hello ' ]() / 100 * ' foo ' <Dingus root.something.__rpow__[hello]().__div__.__mul__>
(Hoffentlich werden Ihre realen Dingus-Aufnahmen nicht so aussehen!)
Dingus bietet einen Kontextmanager für das Patchen von Objekten während der Tests. Zum Beispiel:
>>> from dingus import patch >>> import urllib2 >>> with patch( ' urllib2.urlopen ' ): ... print urllib2.urlopen. __class__ <class 'dingus.Dingus'> >>> print urllib2.urlopen. __class__ <type 'function'>
Sie können dies auch als Dekorateur für Ihre Testmethoden verwenden:
>>> @ patch( ' urllib2.urlopen ' ) ... def test_something ( self ): ... pass ...
Das Gegenteil von Patch ist isoliert. Es flickt alles außer dem benannten Objekt:
>>> from dingus import isolate >>> @ isolate( ' urllib2.urlparse ' ) ... def test_urlparse ( self ): ... pass ...
Wenn dieser Test ausgeführt wird, ist alles im URLLIB2 -Modul mit Ausnahme von Urlparse ein Dingus. Beachten Sie, dass dies möglicherweise nur langsam ausgeführt wird, wenn das Modul viele Objekte enthält. Performance -Patches sind willkommen. :)
Dingus kann beim Ausführen von Tests auch automatisch die Globalen eines Moduls ersetzen. Auf diese Weise können Sie vollständig isolierte Unit -Tests schreiben. Beispiele/urllib2/test_urllib2.py für ein Beispiel. Der Autor empfiehlt diese Funktion nicht mehr, da er sehr spröde Tests fördern kann. Sie sollten den Schmerz verspüren, die Abhängigkeiten manuell verspottet zu haben. Der Schmerz wird Ihnen sagen, wenn eine Klasse mit zu vielen anderen zusammenarbeitet.