2012-04-04 3 views
9

Ho un decoratore e voglio affermare che certi metodi nel mio codice sono decorati con esso.Come affermare che un metodo è decorato 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 

Come posso affermare con unittest (unitttest2) che ha my_method@decorator e nessuno rimosso, e non è stato dimenticato?

+3

fare alcuni controlli che mettono alla prova se la funzione (non è chiamato un "metodo" in Python, btw) ha il comportamento corretto, aumentando le eccezioni corrette ecc. Se lo fa, va tutto bene. –

+0

ha aggiornato l'esempio per avere un metodo reale invece di una semplice funzione del modulo pendente. – Evgeny

+0

Con i test unitari, si verifica solo se la funzione fa la cosa giusta. Il punto è che le persone possono refactoring l'implementazione reale come vogliono, purché non rompere la funzionalità. Quello che stai cercando di fare non ha nulla a che fare con i test unitari. –

risposta

2

È possibile fare affidamento sul proprio decoratore per contrassegnare la funzione wrapper con un attributo, che quindi si asserisce.

Una buona pratica è che il decoratore abbia impostato un attributo __wrapped__ che punta alla funzione originale sul wrapper restituito.

così:

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 

e poi, sul codice di prova:

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

L'attributo che contiene la funzione wrapped deve essere chiamato ['__wrapped__'] (http : //docs.python.org/py3k/library/functools.html#functools.update_wrapper). –

+0

Evggeny: hai testato le modifiche che hai apportato alla mia risposta? retriveng hte method weithout alla classe '__dict__', in Python 2.x, fornisce un metodo associato - no l'oggetto funzione - Non penso che il metodo associato copi l'attributo' __wrapped__' della funzione sottostante. Oh, l'ho provato ora, in effetti, l'oggetto metodo trasmette gli accessi agli attributi degli oggetti funzione - non lo sapevo. – jsbueno

+0

http://pastie.org/3728502 – jsbueno

4

Se per qualche motivo non è possibile modificare il decoratore, si potrebbe anche provare il controllo di alcune caratteristiche di un variabile chiusa.

Nel tuo esempio, si sa che l'originale my_method è l'unica variabile chiusa dal decoratore, così si potrebbe:

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