如何模拟装饰函数 [英] How to mock a decorated function

查看:80
本文介绍了如何模拟装饰函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For testing reasons, I need to be able to mock the inner/original function of a decorated one which is used somewhere else:

在mydecorator.py中:

In 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,另一个版本为 naked。运行器函数run_decorated()调用装饰性版本的function_to_be_mocked,run_undecorated()调用未装饰性版本,并手动应用装饰器。两者的结果相同:

As you can see, I have several versions of the original function function_to_be_mocked, one with the decorator my_decorator and one 'naked'. The runner function run_decorated() calls the decorated version of function_to_be_mocked and run_undecorated() calls the undecorated version and applies the decorator 'manually'. The result of both are the same:

decorated
original

现在我想测试运行器功能,但我需要模拟原始功能function_to_be_mocked,但模拟版本也应修饰:

Now I want to test the runner function but I need to mock the original function function_to_be_mocked but also the mocked version should be decorated:

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可以正常工作:

This works as expected for the undecorated version test_undecorated_mocked:

decorated
mockified

但修饰后的版本给出:

mockified

所以装饰器消失了。

是否可以使装饰版本与未装饰版本(以手动方式应用装饰器)相同的方式工作?

Is it possible to get the decorated version working in the same way as the undecorated version, where the decorator is applied 'manually'?

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

I tried to expose the inner function in the decorator without success.

我看到了这个问题如何模拟具有装饰器的功能但这对我没有帮助。

I saw this question How do you mock a function which has decorator apply to it in a unit test? but this doesn't help me.

推荐答案

Python在加载模块,因此在 test_decoratorated_mocked 中将 function_to_be_mocked 设置为 mock_function 确实会发生变化

Python applies the decorator when loading the module so setting function_to_be_mocked to mock_function in test_decoratorated_mocked would indeed change that function into an undecorated function.

如果要模拟 function_to_be_mocked :

mydecorator.function_to_be_mocked = mydecorator.my_decorator(mock_function)

这篇关于如何模拟装饰函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆