Un dingus es como un objeto simulado. La principal diferencia es que no establece expectativas con anticipación. Simplemente ejecuta su código, usando un Dingus en lugar de otro objeto o clase, y registrará lo que le sucede. Luego, una vez que se haya ejercido su código, puede hacer afirmaciones sobre lo que le hizo al Dingus.
Se crea un nuevo Dingus a partir de la clase Dingus. Puede dar nombres de dinguses, que ayudan a depurar sus pruebas, especialmente cuando hay múltiples dinguses en juego.
>>> from dingus import Dingus >>> d = Dingus( ' root ' ) >>> d <Dingus root>
Acceder a cualquier atributo de un Dingus devolverá un nuevo Dingus.
>>> d.something <Dingus root.something>
Hay algunas excepciones para métodos especiales de Dingus. Veremos algunos en un momento.
Un Dingus también se puede llamar como una función o método. No le importa cuántos argumentos le da o cuáles son esos argumentos. Las llamadas a un Dingus siempre devolverán el mismo objeto, independientemente de los argumentos.
>>> d() <Dingus root()> >>> d( ' argument ' ) <Dingus root()> >>> d( 55 ) <Dingus root()>
En cualquier momento podemos obtener una lista de llamadas que se han hecho a un Dingus. Cada entrada en la lista de llamadas contiene:
Aquí hay una lista de las llamadas que hemos hecho a D hasta ahora:
>>> from pprint import pprint >>> pprint(d.calls) [('()', (), {}, <Dingus root()>), ('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
Puede filtrar llamadas por nombre, argumentos y argumentos de palabras clave:
>>> pprint(d.calls( ' () ' , 55 )) [('()', (55,), {}, <Dingus root()>)]
Si no le importa el valor de un argumento en particular, puede usar el valor que no se filtra: se filtra:
>>> from dingus import DontCare >>> pprint(d.calls( ' () ' , DontCare)) [('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
Los dinguses pueden hacer más que solo los atributos accedidos y llamados. Apoyan a muchos operadores de Python. El objetivo es permitir y registrar cualquier interacción:
>>> d = Dingus( ' root ' ) >>> ( 2 ** d.something)[ ' hello ' ]() / 100 * ' foo ' <Dingus root.something.__rpow__[hello]().__div__.__mul__>
(¡Ojalá tus grabaciones de Dingus del mundo real no se verán así!)
Dingus proporciona un administrador de contexto para parchear objetos durante las pruebas. Por ejemplo:
>>> from dingus import patch >>> import urllib2 >>> with patch( ' urllib2.urlopen ' ): ... print urllib2.urlopen. __class__ <class 'dingus.Dingus'> >>> print urllib2.urlopen. __class__ <type 'function'>
También puede usar esto como decorador en sus métodos de prueba:
>>> @ patch( ' urllib2.urlopen ' ) ... def test_something ( self ): ... pass ...
Lo opuesto al parche es aislado. Parche todo excepto el objeto nombrado:
>>> from dingus import isolate >>> @ isolate( ' urllib2.urlparse ' ) ... def test_urlparse ( self ): ... pass ...
Cuando se ejecuta esta prueba, todo en el módulo Urllib2, excepto Urlparse, será un Dingus. Tenga en cuenta que esto puede ser lento para ejecutar si el módulo contiene muchos objetos; Los parches de rendimiento son bienvenidos. :)
Dingus también puede reemplazar automáticamente los globales de un módulo al ejecutar pruebas. Esto le permite escribir pruebas unitarias totalmente aisladas. Ver ejemplos/urllib2/test_urllib2.py para un ejemplo. El autor ya no recomienda esta característica, ya que puede fomentar pruebas muy frágiles. Debe sentir el dolor de burlarse manualmente dependencias; El dolor le dirá cuándo una clase colabora con demasiados otros.