相关疑难解决方法(0)

如何模拟装饰功能

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

在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()
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我有几个版本的原始函数function_to_be_mocked,一个带有装饰器my_decorator,一个带有'裸'.runner函数run_decorated()调用function_to_be_mocked的装饰版本,run_undecorated()调用未修饰版本并"手动"应用装饰器.两者的结果是相同的:

decorated
original
Run Code Online (Sandbox Code Playgroud)

现在我想测试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
Run Code Online (Sandbox Code Playgroud)

这对于未修饰版本test_undecorated_mocked的预期效果如下:

decorated
mockified
Run Code Online (Sandbox Code Playgroud)

但装饰版本给出:

mockified
Run Code Online (Sandbox Code Playgroud)

所以装饰师消失了.

是否有可能使装饰版本的工作方式与未修改版本相同,其中装饰器是"手动"应用的?

我试图在装饰器中公开内部函数但没有成功.

我看到了这个问题你如何在单元测试中模拟一个装饰器适用于它的函数?但这对我没有帮助.

python unit-testing monkeypatching mocking decorator

16
推荐指数
1
解决办法
6416
查看次数