2012-04-04 5 views
9

У меня есть декоратор, и я хочу утверждать, что некоторые методы в моем коде украшены им.Как утверждать, что метод украшен 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 

Как утверждают с UnitTest (unitttest2), что my_method имеет @decorator, и никто не снял его, и он не был забыт?

+3

ли какие-либо проверки, которые проверяют, если функция (это не называется «метод» в Python, btw) имеет правильное поведение, поднимая правильные исключения и т. Д. Если это так, все в порядке. –

+0

обновил пример, чтобы иметь реальный метод, а не только функцию висячего модуля. – Evgeny

+0

С модульными тестами вы проверяете только правильность функции. Все дело в том, что люди могут реорганизовать фактическую реализацию по своему усмотрению, если они не нарушают функциональность. То, что вы пытаетесь сделать, не имеет ничего общего с модульным тестированием. –

ответ

2

Вы можете сделать это, опираясь на свой декоратор, чтобы отметить функцию-оболочку атрибутом, который вы затем утверждаете.

Хорошая практика заключается в том, чтобы декоратор установил атрибут __wrapped__, указывающий на исходную функцию на возвращенной оболочке.

таким образом:

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 

, а затем, на ваш тестовый код:

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

Атрибут, содержащий обернутую функцию, должен называться ['__wrapped__'] (http : //docs.python.org/py3k/library/functools.html#functools.update_wrapper). –

+0

Evggeny: вы проверили изменения, которые вы внесли в мой ответ? retriveng hte метод weithout класса '__dict__', в Python 2.x, дает вам связанный метод - нет объекта функции - я не думаю, что связанный метод копирует атрибут' __wrapped__' базовой функции. О - я протестировал его сейчас, действительно, объект метода проксирует доступ к атрибутам объекта функции - я этого не знал. – jsbueno

+0

http://pastie.org/3728502 – jsbueno

4

Если по каким-то причинам вы не можете изменить декоратора, вы можете также попытаться проверить для некоторой характеристики закрытая переменная.

В вашем примере, вы знаете, что первоначальный my_method является единственной переменной закрыто декоратора, так что вы могли бы:

assert (my_method.__closure__ and 
      my_method.__closure__[0].cell_contents.__name__ == my_method.__name__) 
Смежные вопросы