在Python 2.7 / 3.5

时间:2016-06-15 10:15:44

标签: python python-2.7 mocking class-method

我正在尝试将classmethods动态添加到Python 2.7类中。我还在3.5.1中测试了同样的问题,同样的事情发生了。这个目的是用于单元测试模拟。这里的答案How to add a classmethod in Python dynamically似乎是相关的,但是当继承也发挥作用时它们似乎会破裂。当我使用我的mock时,cls绑定总是得到父类,而不是我称之为classmethod的类。为什么会发生这种情况?我如何实现嘲弄类方法并在cls中获得正确的类?

class Parent(object):
    @classmethod
    def clm(cls):
        return 'Orig:' + cls.__name__

class Child(Parent):
    pass

print 'Parent:', Parent.clm()
# Parent: Orig:Parent as expected
print 'Child:', Child.clm()
# Child: Orig:Child as expected as well, because cls is Child

def mock_clm(cls):
    return 'Ovr:' + cls.original_clm()

# Save the original and replace with mock function    
Parent.original_clm = Parent.clm
Parent.clm = classmethod(mock_clm)

print 'Parent:', Parent.clm()
# Parent: Ovr:Orig:Parent as expected, our mock function is called
print 'Child:', Child.clm()
# Child: Ovr:Orig:Parent! What I wanted here is to get Ovr:Orig:Child
# but for some reason the classmethod cls binding breaks and returns
# Parent instead

# Note how original_clm doesn't bind as I expected as well
print 'Parent:', Parent.original_clm()
print 'Child:', Child.original_clm()

我尝试了各种其他的模拟方法,比如使用mock.patch,在父类上使用setattr并将装饰器添加到函数中而不是在assigment上使用它,都具有相同的效果。这是使用mock的示例代码,它产生相同的结果:

import mock
with mock.patch('__main__.Parent.clm', classmethod(mock_clm)):
    print 'Parent:', Parent.clm()
    # Parent: Ovr:Orig:Parent
    print 'Child:', Child.clm()
    # Child: Ovr:Orig:Parent

0 个答案:

没有答案