如何在python中模拟/修补装饰器?

Bod*_*dao 6 python mocking python-3.x

解决方法:

我无法修补装饰器,但仍然可以访问包装的函数。但是我要测试包装在装饰器中的函数的解决方法如下:

def un_some_method(self):
...

some_method = some_var.some_decorator('somestring')(un_some_method)    
Run Code Online (Sandbox Code Playgroud)

这仍然修饰了我的功能,但是如果我想对其进行测试,可以在其他地方重用它,则可以访问该功能。

这就是问题:

我有一个模块,其中有一个类,以及实例化暴露装饰器的类的变量。

然后在模块内部的类中,将该变量与类的实例一起使用,并在类中装饰一个方法。要清楚,让我们看一些代码:

some_var = ClassX()

class SomeClass(object):

    @some_var.some_decorator('somestring')
    def some_method(self):
        ...
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我想测试其中的代码,some_method并且我不在乎装饰器...尽管我尝试模拟装饰器是没有用的...以下是我尝试过的一些事情:

@patch('path_to_classx.ClassX.some_decorator')
@patch('path_to_someclassmodule.some_var')
@patch('path_to_someclassmodule.ClassX')
Run Code Online (Sandbox Code Playgroud)

上面的尝试都没有阻止功能的修饰...知道为什么吗?

che*_*ner 2

一种选择是some_var在实例化它之后进行修补,some_decorator用恒等函数替换,以便修饰的方法保持不变。

import mock
class ClassX(object):
    def some_decorator(self, f):
        def g(*args, **kwargs):
            print("Hello")
            return f(*args, **kwargs)
        return g

some_var = ClassX()

with mock.patch.object(some_var, 'some_decorator', side_effect=lambda f: f):

    class SomeClass(object):
        @some_var.some_decorator
        def some_method(self):
            print "World"


SomeClass().some_method()
Run Code Online (Sandbox Code Playgroud)