2012-04-04 12 views
9

Mam dekoratora i chcę potwierdzić, że niektóre metody w moim kodzie są z niego ozdobione.Jak twierdzić, że metoda jest ozdobiona 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 

Jak mogę dochodzić z unittest (unitttest2), które my_method ma @decorator i nikt nie usuwa go, a on nie został zapomniany?

+3

Czy jakieś kontrole sprawdzające, czy funkcja (nie nazywa się „metoda” w Python, btw) ma prawidłowe zachowanie, podnosząc poprawne wyjątki itp. Jeśli tak, wszystko jest w porządku. –

+0

zaktualizował przykład, aby mieć prawdziwą metodę zamiast tylko funkcji modułu zwisającego. – Evgeny

+0

Podczas testów jednostkowych testuje się tylko, czy funkcja działa prawidłowo. Chodzi o to, że ludzie mogą refaktoryzować rzeczywistą implementację tak, jak chcą, o ile nie łamią funkcjonalności. To, co próbujesz zrobić, nie ma nic wspólnego z testowaniem jednostkowym. –

Odpowiedz

2

Możesz to zrobić, opierając się na dekoratorze, aby oznaczyć funkcję opakowania atrybutem, który następnie potwierdzasz.

Dobrą praktyką jest ustawienie zestawu dekoratorów na atrybut __wrapped__ wskazujący na oryginalną funkcję zwróconego opakowania.

tak:

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 

a następnie w kodzie testowym:

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

Atrybut trzymający owiniętą funkcję powinien być wywołany ['__wrapped__'] (http : //docs.python.org/py3k/library/functools.html#functools.update_wrapper). –

+0

Evggeny: czy przetestowałeś zmiany wprowadzone w mojej odpowiedzi? retriveng metoda hte bez klasy "__dict__", w Pythonie 2.x, daje metodę związaną - nie obiekt funkcji - nie sądzę, że związana metoda kopiuje atrybut "__wrapped__" funkcji podstawowej. Och, przetestowałem to teraz, w rzeczy samej, obiekt metody prosi o dostęp do atrybutów obiektów funkcyjnych - nie wiedziałem o tym. – jsbueno

+0

http://pastie.org/3728502 – jsbueno

4

Jeśli z jakiegoś powodu nie możesz modyfikować dekorator, można także spróbować sprawdzanie jakiś charakterystyczny zamknięta zmienna.

W przykładzie, wiesz, że oryginalne my_method jest jedyną zmienną zamknięty przez dekoratora, więc może:

assert (my_method.__closure__ and 
      my_method.__closure__[0].cell_contents.__name__ == my_method.__name__) 
Powiązane problemy