5

我有一堂课:

class MyClass(object):
    @property
    def myproperty(self):
        return 'hello'

使用moxand py.test,我如何模拟出来myproperty

我试过了:

mock.StubOutWithMock(myclass, 'myproperty')
myclass.myproperty = 'goodbye'

mock.StubOutWithMock(myclass, 'myproperty')
myclass.myproperty.AndReturns('goodbye')

但两者都失败了AttributeError: can't set attribute

4

2 回答 2

9

当存根类属性时,mox使用setattr. 因此

mock.StubOutWithMock(myinstance, 'myproperty')
myinstance.myproperty = 'goodbye'

相当于

# Save old attribute so it can be replaced during teardown
saved = getattr(myinstance, 'myproperty')
# Replace the existing attribute with a mock
mocked = MockAnything()
setattr(myinstance, 'myproperty', mocked)

请注意,因为myproperty是一个属性getattrsetattr将调用该属性__get____set__方法,而不是实际“模拟”该属性本身。

因此,要获得您想要的结果,您只需更深入一步并模拟实例类上的属性。

mock.StubOutWithMock(myinstance.__class__, 'myproperty')
myinstance.myproperty = 'goodbye'

请注意,如果您希望同时模拟具有不同myproperty值的多个 MyClass 实例,这可能会导致问题。

于 2010-03-25T22:06:42.697 回答
3

你读过财产吗?它是只读的,是一个“getter”。

如果你想要一个二传手,你有两种选择如何创建它。

一旦你拥有了 getter 和 setter,你就可以再次尝试模拟出它们。

class MyClass(object): # Upper Case Names for Classes.
    @property
    def myproperty(self):
        return 'hello'
    @myproperty.setter
    def myproperty(self,value):
        self.someValue= value

或者

class MyClass(object): # Upper Case Names for Classes.
    def getProperty(self):
        return 'hello'
    def setProperty(self,value):
        self.someValue= value
    myproperty= property( getProperty, setProperty )
于 2010-03-25T10:17:59.620 回答