2010-01-14 29 views
10

Dado:Python - probar una propiedad lanza excepción

def test_to_check_exception_is_thrown(self): 
    # Arrange 
    c = Class() 
    # Act and Assert 
    self.assertRaises(NameError, c.do_something) 

Si do_something se emite una excepción pasa la prueba.

Pero tengo una propiedad, y cuando reemplazo c.do_something con c.name = "Name" recibo un error acerca de que mi Módulo de prueba no se importa y Eclipse resalta el símbolo de igual.

¿Cómo puedo probar una propiedad arroja una excepción?

Editar:

setattr y getattr son nuevas para mí. Ciertamente han ayudado en este caso, gracias.

Respuesta

13

assertRaises espera una objeto invocable Puede crear una función y lo pasa:

obj = Class() 
def setNameTest(): 
    obj.name = "Name"   
self.assertRaises(NameError, setNameTest) 

Otra posibilidad es utilizar setattr:

self.assertRaises(NameError, setattr, obj, "name", "Name") 

Su código original plantea un error de sintaxis, porque la asignación es una declaración y no puede ser colocado dentro de una expresión.

+2

Dado que Python 2.7+ debe realizar el pago @RaphaelAhrens, responda a continuación. Es mucho más pythonic http: // stackoverflow.com/a/23650764/601245 –

-1

Aparecerá un error porque es un error de sintaxis en Python tener una tarea dentro de otra expresión. Por ejemplo:

>>> print(foo = 'bar') 
------------------------------------------------------------ 
    File "<ipython console>", line 1 
    print(foo = 'bar') 
      ^
SyntaxError: invalid syntax 

Pero hacerlo en dos pasos funciona bien:

>>> foo = 'bar' 
>>> print(foo) 
bar 

Para probar que una propiedad se produce una excepción, utilice un bloque try:

try: 
    object.property = 'error' 
except ExpectedError: 
    test_passes() 
else: 
    test_fails() 
+0

Esto es excesivo y no encaja realmente en el uso de unittest. –

8

The second argument to assertRaises should be a callable.

Una declaración de asignación (es decir, class.name = "Name") no se puede llamar, por lo que no funcionará. Utilice setattr para llevar a cabo la asignación al igual que

self.assertRaises(NameError, setattr, myclass, "name", "Name") 

Además, no se puede asignar a class ya que es una palabra clave.

+0

Fue un pseudo código, para reflejar mi código. Pero yo sé ;) – Finglas

10

Dado que Python 2.7 y 3.1 assertRaises() se puede utilizar como administrador de contexto. Ver here for Python 2 y here for Python3.

para que pueda escribir su prueba con la instrucción with así:

def test_to_check_exception_is_thrown(self): 
    c = Class() 
    with self.assertRaises(NameError): 
     c.name = "Name" 
0

Como @interjay se ha dicho, está esperando un callble, pero ou realmente no necesita definir una función llamada para esto, una lambda lo hará:

self.assertRaises(SomeException, lambda: my_instance.some_property) 
Cuestiones relacionadas