出于测试原因,我需要能够模拟在其他地方使用的装饰的内部/原始功能:
在mydecorator.py中:
def my_decorator(f):
def wrapped_f():
print "decorated"
f()
return wrapped_f
@my_decorator
def function_to_be_mocked():
print 'original'
def function_to_be_mocked_undecorated():
print 'original'
def run_decorated():
function_to_be_mocked()
def run_undecorated():
decorated_funtion = my_decorator(function_to_be_mocked_undecorated)
decorated_funtion()
正如你所看到的,我有几个版本的原始函数function_to_be_mocked,一个带有装饰器my_decorator,一个带有'裸'。 runner函数run_decorated()调用function_to_be_mocked的装饰版本,run_undecorated()调用未修饰的版本并“手动”应用装饰器。两者的结果是相同的:
decorated
original
现在我想测试转轮功能,但是我需要模拟原始函数function_to_be_mocked,但是应该修饰模拟版本:
import unittest
import mydecorator
from mock import patch
def mock_function():
print 'mockified'
class Test(unittest.TestCase):
@patch('mydecorator.function_to_be_mocked_undecorated')
def test_undecorated_mocked(self, mock_function_to_be_mocked_undecorated):
mydecorator.function_to_be_mocked_undecorated = mock_function
mydecorator.run_undecorated()
assert 1==0
@patch('mydecorator.function_to_be_mocked')
def test_decoratorated_mocked(self, mock_function_to_be_mocked):
mydecorator.function_to_be_mocked = mock_function
mydecorator.run_decorated()
assert 1==0
这对于未修饰版本test_undecorated_mocked:
的预期效果decorated
mockified
但装饰版本给出了:
mockified
所以装饰师消失了。
是否有可能使装饰版本的工作方式与未修饰版本相同,其中装饰器是“手动”应用的?
我试图在装饰器中公开内部函数但没有成功。
我看到了这个问题How do you mock a function which has decorator apply to it in a unit test?,但这对我没有帮助。
答案 0 :(得分:14)
Python在加载模块时应用装饰器,因此在function_to_be_mocked
中将mock_function
设置为test_decoratorated_mocked
确实会将该函数更改为未修饰的函数。
如果您想模拟function_to_be_mocked
:
mydecorator.function_to_be_mocked = mydecorator.my_decorator(mock_function)