出于测试原因,我需要能够模拟在其他地方使用的经过修饰的内部/原始功能:
在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,另一个版本为“裸”。运行器函数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
所以装饰师消失了。
装饰版本是否可以与装饰版本“手动”应用的未装饰版本相同?
我试图在装饰器中公开内部函数,但没有成功。
Python在加载模块时会应用装饰器,因此设置function_to_be_mocked为mock_functionintest_decoratorated_mocked确实会将该函数更改为未修饰的函数。
function_to_be_mocked
mock_function
test_decoratorated_mocked
如果要模拟,则需要再次手动添加装饰器function_to_be_mocked:
mydecorator.function_to_be_mocked = mydecorator.my_decorator(mock_function)