2010-01-14 12 views
10

Data:Python - testare una proprietà genera un'eccezione

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

Se do_something genera un'eccezione il test viene superato.

Ma ho una proprietà, e quando sostituisco c.do_something con c.name = "Name" ottengo un errore sul mio modulo di test non importato ed Eclipse evidenzia il simbolo di uguale.

Come si verifica una proprietà genera un'eccezione?

Edit:

setattr e getattr sono nuovi per me. Hanno sicuramente aiutato in questo caso, grazie.

risposta

13

assertRaises aspetta una oggetto callable. È possibile creare una funzione e passarlo:

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

Un'altra possibilità è quella di utilizzare setattr:

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

tuo codice originale genera un errore di sintassi, perché l'assegnazione è una dichiarazione e non può essere inserito all'interno di un'espressione.

+2

Poiché python 2.7+ deve eseguire il checkout della risposta @RaphaelAhrens di seguito. È molto più pythonic http: // StackOverflow.it/a/23650764/601245 –

-1

Si riceve un errore perché si tratta di un errore di sintassi in Python per assegnare un compito all'interno di un'altra espressione. Per esempio:

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

Ma farlo in due fasi funziona bene:

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

Per verificare che una proprietà genera un'eccezione, utilizzare un blocco try:

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

Questo è eccessivo e non si adatta perfettamente all'utilizzo di unittest. –

8

The second argument to assertRaises should be a callable.

Un estratto conto (ad esempio class.name = "Name") non è un chiamabile, quindi non funzionerà. Utilizzare setattr per effettuare l'assegnazione in questo modo

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

Inoltre, non è possibile assegnare ad class dal momento che è una parola chiave.

+0

Era pseudo codice, per rispecchiare il mio codice. Ma io so ;) – Finglas

10

Poiché Python 2.7 e 3.1 assertRaises() possono essere utilizzati come gestore di contesto. Vedi here for Python 2 e here for Python3.

modo da poter scrivere il test con l'istruzione with in questo modo:

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

Come @interjay detto, si aspetta un callble, ma ou non ha realmente bisogno di definire una funzione denominata per questo, un lambda lo farà:

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