我有一个班级:
class MyClass(object):
@property
def myproperty(self):
return 'hello'
使用mox
和py.test
,如何模拟myproperty
?
我试过了:
mock.StubOutWithMock(myclass, 'myproperty')
myclass.myproperty = 'goodbye'
和
mock.StubOutWithMock(myclass, 'myproperty')
myclass.myproperty.AndReturns('goodbye')
但两者均以AttributeError: can't set attribute
失败。
答案 0 :(得分: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
是属性getattr
而setattr
将调用属性的__get__
和__set__
方法,而不是实际“嘲笑”该物业本身。
因此,为了获得您想要的结果,您只需更深入一步并在实例的类上嘲笑该属性。
mock.StubOutWithMock(myinstance.__class__, 'myproperty')
myinstance.myproperty = 'goodbye'
请注意,如果您希望同时模拟具有不同myproperty
值的MyClass的多个实例,则可能会出现问题。
答案 1 :(得分:3)
您是否了解过property?它是只读的,是“吸气剂”。
如果你想要一个setter,你有两种选择如何创建它。
一旦你同时拥有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 )