Как мне макетировать свойство класса с помощью mox?
У меня есть класс:
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
,
2 ответа
При заглушении атрибутов класса 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'
Обратите внимание, что это может вызвать проблемы, если вы хотите одновременно смоделировать несколько экземпляров MyClass с разными myproperty
ценности.
Вы читали о собственности? Это только для чтения, "добытчик".
Если вам нужен сеттер, у вас есть два варианта, как его создать.
Как только у вас есть и геттер, и сеттер, вы можете попытаться повторить их оба.
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 )