2010-03-25 15 views
5

tengo una clase:¿Cómo me burlo de una propiedad de clase con mox?

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

Usando mox y py.test, ¿cómo me burlo cabo myproperty?

que he probado:

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

y

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

pero ambos fallan con AttributeError: can't set attribute.

+1

Utilice mayúsculas y minúsculas para las clases. –

Respuesta

9

Cuando apagando los atributos de clase mox utiliza setattr. Por lo tanto

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

es equivalente a

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

Tenga en cuenta que debido a myproperty es una propiedad getattr y setattr se invocando __get__ y __set__ métodos de la propiedad, en lugar de realmente "burla a cabo" la propiedad en sí.

Por lo tanto, para obtener el resultado deseado solo tiene que ir un paso más allá y burlarse de la propiedad en la clase de la instancia.

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

Tenga en cuenta que esto podría causar problemas si se desea al mismo tiempo simulacros de varias instancias de MyClass con diferentes valores myproperty.

3

¿Has leído sobre property? Es de solo lectura, un "getter".

Si desea un colocador, tiene dos opciones de cómo crearlo.

Una vez que tenga tanto getter como setter, puede volver a intentar simular ambos.

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

O

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

Sí, yo esperaba salirse con la suya sin modificar la clase original, sin embargo, puede que no sea posible. –

+2

No puedes burlarte de algo que no existe. La clase original no pudo tener el conjunto de propiedades. No puede burlarse de esa función porque no existe. –

Cuestiones relacionadas