2010-01-14 4 views
10

Vu:Python - tester une propriété émet une exception

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

Si do_something déclenche une exception le test passe.

Mais j'ai une propriété, et quand je remplacerai c.do_something avec c.name = "Name" je reçois une erreur au sujet de mon module de test ne sont pas importées et Eclipse met en évidence le symbole égal.

Comment tester une propriété en lançant une exception?

Edit:

setattr et getattr sont nouveaux pour moi. Ils ont certainement aidé dans ce cas, merci.

Répondre

13

assertRaises attend un objet appelable. Vous pouvez créer une fonction et passez:

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

Une autre possibilité est d'utiliser setattr:

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

Votre code d'origine soulève une erreur de syntaxe parce que la cession est une déclaration et ne peut pas être placé dans une expression.

+2

Depuis python 2.7+ devrait checkout @RaphaelAhrens réponse ci-dessous. C'est beaucoup plus pythonique http: // stackoverflow.com/a/23650764/601245 –

-1

Vous obtenez une erreur car c'est une erreur de syntaxe en Python d'avoir une affectation dans une autre expression. Par exemple:

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

Mais le faire en deux étapes fonctionne très bien:

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

Pour tester une propriété lance une exception, utilisez un bloc try:

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

Ceci est excessif et ne correspond pas vraiment à l'utilisation d'unittest. –

8

The second argument to assertRaises should be a callable.

Une instruction d'affectation (par exemple, class.name = "Name") n'est pas appelable, elle ne fonctionnera donc pas. Utilisez setattr pour effectuer l'affectation comme si

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

, vous pouvez aussi ne pas céder à class car il est un mot-clé.

+0

C'était un pseudo code, pour refléter mon code. Mais je sais ;) – Finglas

10

Depuis Python 2.7 et 3.1 assertRaises() peut être utilisé comme un gestionnaire de contexte. Voir here for Python 2 et here for Python3.

Vous pouvez écrire votre test avec l'instruction with comme ceci:

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

Comme @interjay dit, il attend un callble, mais ous ne vraiment pas besoin de définir une fonction nommée pour cela, un lambda le fera:

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