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

如何在python中模拟/修补装饰程序?,python,python-3.x,mocking,Python,Python 3.x,Mocking,解决方法: 我无法修补装饰程序,仍然可以访问包装的函数。但我测试包装在装饰器中的函数的解决方法如下: def un_some_method(self): ... some_method = some_var.some_decorator('somestring')(un_some_method) 这仍然装饰了我的函数,但是如果我想测试它,在其他地方重用它,我就可以访问它 这就是问题所在: 我有一个模块,其中有一个类,以及实例化一个类的变量,该类公开了一个装饰器 然后在模块内的类中,我

解决方法:

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

def un_some_method(self):
...

some_method = some_var.some_decorator('somestring')(un_some_method)    
这仍然装饰了我的函数,但是如果我想测试它,在其他地方重用它,我就可以访问它

这就是问题所在:

我有一个模块,其中有一个类,以及实例化一个类的变量,该类公开了一个装饰器

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

some_var = ClassX()

class SomeClass(object):

    @some_var.some_decorator('somestring')
    def some_method(self):
        ...
在我的测试中,我想在
某个方法中测试代码,我不关心装饰器。。。虽然我试图嘲弄装饰师是徒劳的。。。以下是我尝试过的一些事情:

@patch('path_to_classx.ClassX.some_decorator')
@patch('path_to_someclassmodule.some_var')
@patch('path_to_someclassmodule.ClassX')

上述尝试均未阻止对函数进行装饰。。。知道为什么吗?

一个选项是在实例化
某些变量之后对其进行修补,用标识函数替换
某些修饰符
,从而使修饰的方法保持不变

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

这是一个非常有趣的问题,但我只是好奇:如果decorator是代码的一部分,为什么要禁用它?因为decorator中的代码是在其他地方测试的,为了保持测试单元的概念,让函数的结果填充decorator以获得不同的结果似乎打破了这一规则。。。另外,如果decorator坏了,它会破坏我使用decorator的测试,这可能是误导性的?我知道你不希望你的函数与一个可能坏掉的decorator纠缠在一起。但是被测试的函数必须在修饰状态下正常运行,不是吗?如果这是真的,我有理由用设计好的装饰器来测试它。也许您可以设计一组条件来隔离decorator与被测函数之间的故障?在我看来,如果测试失败,不管是什么原因,它都必须被重构。我从来没有像你一样嘲笑过一个装饰者,当我试图用一个测试用例来回答你的问题时,我也无法让它工作……这听起来有点奇怪,但现在当装饰者被触发时,我得到了一个错误“object not callable”(对象不可调用),不确定我是否做错了什么,请随时通知你,谢谢!好的,这显然是可行的,但问题是我的decorator接受一个参数,它是一个字符串,所以lambda将返回字符串而不是函数。。。有什么想法吗?示例:@some_var.some_decorator('somestring'),这是您需要在原始问题中包含的详细信息。