Un Dingus est un peu comme un objet simulé. La principale différence est que vous ne créez pas les attentes à l'avance. Vous exécutez simplement votre code, en utilisant un Dingus à la place d'un autre objet ou classe, et il enregistrera ce qui lui arrivera. Ensuite, une fois votre code exercé, vous pouvez faire des affirmations sur ce qu'elle a fait au Dingus.
Un nouveau Dingus est créé à partir de la classe Dingus. Vous pouvez donner des noms de Dingus, ce qui aide à déboguer vos tests, en particulier lorsqu'il y a plusieurs dingus en jeu.
>>> from dingus import Dingus >>> d = Dingus( ' root ' ) >>> d <Dingus root>
L'accès à tout attribut d'un Dingus renverra un nouveau Dingus.
>>> d.something <Dingus root.something>
Il existe quelques exceptions pour les méthodes spéciales de Dingus. Nous en verrons un peu.
Un Dingus peut également être appelé comme une fonction ou une méthode. Il ne se soucie pas du nombre d'arguments que vous lui donnez ni de ces arguments. Les appels à un Dingus rendront toujours le même objet, quels que soient les arguments.
>>> d() <Dingus root()> >>> d( ' argument ' ) <Dingus root()> >>> d( 55 ) <Dingus root()>
À tout moment, nous pouvons obtenir une liste d'appels qui ont été passés à un Dingus. Chaque entrée de la liste des appels contient:
Voici une liste des appels que nous avons passés jusqu'à présent: jusqu'à présent:
>>> from pprint import pprint >>> pprint(d.calls) [('()', (), {}, <Dingus root()>), ('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
Vous pouvez filtrer les appels par nom, arguments et arguments de mots clés:
>>> pprint(d.calls( ' () ' , 55 )) [('()', (55,), {}, <Dingus root()>)]
Si vous ne vous souciez pas de la valeur d'un argument particulier, vous pouvez utiliser la valeur Dontcare lors du filtrage:
>>> from dingus import DontCare >>> pprint(d.calls( ' () ' , DontCare)) [('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
Dingus peut faire plus que simplement les attributs accessibles et être appelés. Ils soutiennent de nombreux opérateurs Python. L'objectif est de permettre et d'enregistrer toute interaction:
>>> d = Dingus( ' root ' ) >>> ( 2 ** d.something)[ ' hello ' ]() / 100 * ' foo ' <Dingus root.something.__rpow__[hello]().__div__.__mul__>
(J'espère que vos enregistrements de Dingus du monde réel ne ressemblent pas à ça!)
Dingus fournit un gestionnaire de contexte pour corriger les objets lors des tests. Par exemple:
>>> from dingus import patch >>> import urllib2 >>> with patch( ' urllib2.urlopen ' ): ... print urllib2.urlopen. __class__ <class 'dingus.Dingus'> >>> print urllib2.urlopen. __class__ <type 'function'>
Vous pouvez également l'utiliser comme décorateur sur vos méthodes de test:
>>> @ patch( ' urllib2.urlopen ' ) ... def test_something ( self ): ... pass ...
L'opposé du patch est l'isolat. Il patrie tout sauf l'objet nommé:
>>> from dingus import isolate >>> @ isolate( ' urllib2.urlparse ' ) ... def test_urlparse ( self ): ... pass ...
Lorsque ce test s'exécute, tout dans le module Urllib2, sauf Urlparse, sera un Dingus. Notez que cela peut être lent à exécuter si le module contient de nombreux objets; Les correctifs de performance sont les bienvenus. :)
Dingus peut également remplacer automatiquement les globaux d'un module lors de l'exécution de tests. Cela vous permet d'écrire des tests unitaires entièrement isolés. Voir Exemples / Urllib2 / test_urllib2.py pour un exemple. L'auteur ne recommande plus cette fonctionnalité, car elle peut encourager des tests très cassants. Vous devriez ressentir la douleur des dépendances moqueuses manuelles; La douleur vous dira quand une classe collabore avec trop d'autres.