如何模拟修饰函数

2024-09-28 17:28:36 发布

您现在位置:Python中文网/ 问答频道 /正文

出于测试原因,我需要能够模拟装饰的内部/原始功能,该功能在其他地方使用:

在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()

如你所见,我有几个版本的原始功能函数被嘲笑,一个是装饰者我的装饰者,另一个是“裸体”。runner函数run_decorated()调用函数_to_be_mocked的修饰版本,run_undecorated()调用未修饰版本并“手动”应用修饰程序。两者的结果相同:

decorated
original

现在我想测试runner函数,但是我需要模拟原始函数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

这对未修饰版本测试的预期效果是未修饰的:

decorated
mockified

但装饰版给出了:

mockified

所以装饰师消失了。

是否可以让修饰版本以与未修饰版本相同的方式工作,其中修饰程序是“手动”应用的?

我试图暴露装饰器的内部功能,但没有成功。

我看到这个问题,但这对我没有帮助。


Tags: to函数run功能版本deffunction装饰
1条回答
网友
1楼 · 发布于 2024-09-28 17:28:36

Python在加载模块时应用decorator,因此在test_decoratorated_mocked中将function_to_be_mocked设置为mock_function确实会将该函数更改为未修饰的函数。

如果要模拟function_to_be_mocked,则需要再次手动添加装饰程序:

mydecorator.function_to_be_mocked = mydecorator.my_decorator(mock_function)

相关问题 更多 >