2014-03-05 2 views
6

Я хочу, чтобы проверить простой декоратор я написал:питон макет: @wraps (е) проблемы

Это выглядит следующим образом:

#utilities.py 
import other_module 
def decor(f): 
    @wraps(f) 
    def wrapper(*args, **kwds): 
      other_module.startdoingsomething() 
     try: 
      return f(*args, **kwds) 
     finally: 
      other_module.enddoingsomething() 
    return wrapper 

Затем я проверить его с помощью Python-макет:

#test_utilities.py 
def test_decor(self): 
    mock_func = Mock() 
    decorated_func = self.utilities.decor(mock_func) 
    decorated_func(1,2,3) 
    self.assertTrue(self.other_module.startdoingsomething.called) 
    self.assertTrue(self.other_module.enddoingsomething.called) 
    mock_func.assert_called_with(1,2,3) 

Но ногами назад с:

Traceback (most recent call last): 
    File "test_utilities.py", line 25, in test_decor 
    decorated_func = Mock(wraps=self.utilities.decor(mock_func)) 
    File "utilities.py", line 35, in decor 
    @wraps(f) 
    File "/usr/lib/python2.7/functools.py", line 33, in update_wrapper 
    setattr(wrapper, attr, getattr(wrapped, attr)) 
    File "/usr/local/lib/python2.7/dist-packages/mock.py", line 660, in __getattr__ 
    raise AttributeError(name) 
AttributeError: __name__ 

Я знаю, что functools.wraps() - это просто вспомогательная оболочка. Поэтому, если я выберу это, тест будет работать.

Могу ли я заставить Mock играть хорошо с functools.wraps()?

Python 2.7.3

ответ

7

Просто дайте издеваться этот атрибут:

mock_func.__name__ = 'foo' 

Вот именно на самом деле.

Демо:

>>> from functools import wraps 
>>> from mock import Mock 
>>> def decor(f): 
...  @wraps(f) 
...  def wrapper(*args, **kwds): 
...   return f(*args, **kwds) 
...  return wrapper 
... 
>>> mock_func = Mock() 
>>> decor(mock_func) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in decor 
    File ".../opt/lib/python2.7/functools.py", line 33, in update_wrapper 
    setattr(wrapper, attr, getattr(wrapped, attr)) 
    File ".../lib/python2.7/site-packages/mock.py", line 660, in __getattr__ 
    raise AttributeError(name) 
AttributeError: __name__ 
>>> mock_func.__name__ = 'foo' 
>>> decor(mock_func) 
<function foo at 0x10c4321b8> 

Установка __name__ прекрасно подходит; декодер @wraps просто копирует по атрибуту __name__ обертки, а на объектах функций этот атрибут обычно устанавливается в строковое значение. Это атрибут записи для функций в любом случае, и до тех пор, пока вы используете строки function.__name__, можно установить любое значение.

+0

Да, это то, что я только что сделал. Я не был уверен, были ли серьезные последствия. Например, существует «надлежащее» значение. Но тест проходит, поэтому я не думаю, что проблема! Кажется, он был поднят и закрыт здесь: https://code.google.com/p/mock/issues/detail?id=67 – powlo

+0

@paulus_almighty: Любое строковое значение будет выполнено. Все, что вы можете использовать на 'function .__ name__', что угодно, если тип' str'. –

+0

Спасибо, он может хорошо работать. –

 Смежные вопросы

  • Нет связанных вопросов^_^