2012-04-04 9 views
9

Tengo un decorador y quiero afirmar que ciertos métodos en mi código están decorados con él.¿Cómo afirmar que un método está decorado con python unittest?

import functools 

def decorator(func): 
    def _check_something(*args, **kwargs): 
     # some logic in here 
     return func(*args, **kwargs) 
    return functools.wraps(func)(_check_something) 

class MyClass(object): 

    @decorator 
    def my_method(foo, bar): 
     pass 

¿Cómo afirmar con unittest (unitttest2) que tiene my_method@decorator y nadie lo quitó, y no quedó en el olvido?

+3

hacer algunas comprobaciones que ponen a prueba si la función (no se llama un "método" en Python, por cierto) tiene el comportamiento correcto, elevando las excepciones correctas, etc. Si lo hace, todo está bien. –

+0

actualizó el ejemplo para tener un método real en lugar de solo una función de módulo colgante. – Evgeny

+0

Con pruebas unitarias, solo prueba si la función hace lo correcto. El objetivo de todo esto es que las personas puedan refactorizar la implementación real como quieran, siempre que no rompan la funcionalidad. Lo que intentas hacer no tiene nada que ver con las pruebas unitarias. –

Respuesta

2

Puede hacer eso confiando en su decorador para marcar la función de envoltura con un atributo, que luego afirma.

Una buena práctica es hacer que el decorador establezca un atributo __wrapped__ apuntando a la función original en el contenedor devuelto.

así:

def decorator(func): 
    @functools.wraps(func) 
    def _check_something(*args, **kwargs): 
     # some logic in here 
     return func(*args, **kwargs) 
    _check_something.__wrapped__ = func # <== add this 
    return _check_something 

y luego, en su código de prueba:

assert getattr(MyClass.my_method, "__wrapped__").__name__ == 'my_method' 
+1

El atributo que contiene la función envuelta se debe llamar ['__wrapped__'] (http : //docs.python.org/py3k/library/functools.html#functools.update_wrapper). –

+0

Evggeny: ¿has probado las ediciones que has hecho de mi respuesta? Recuperando el método hte sin la clase '__dict__', en Python 2.x, le da un método enlazado - no el objeto función - No creo que el método enlazado copie el atributo' __wrapped__' de la función subyacente. Oh, lo probé ahora, de hecho, el objeto método proxies los accesos a los atributos del objeto de función, no lo sabía. – jsbueno

+0

http://pastie.org/3728502 – jsbueno

4

Si por alguna razón no se puede modificar el decorador, usted podría también intentar comprobar por alguna característica de una variable cerrada.

En su ejemplo, se sabe que el original my_method es la única variable cerrada por el decorador, por lo que podría:

assert (my_method.__closure__ and 
      my_method.__closure__[0].cell_contents.__name__ == my_method.__name__) 
Cuestiones relacionadas