example def __init__ python unit-testing exception

def - ¿Cómo puedo probar un método__init__() de una clase python con assertRaises()?



self en python (3)

Tengo una clase:

class MyClass: def __init__(self, foo): if foo != 1: raise Error("foo is not equal to 1!")

y una prueba unitaria que se supone debe asegurar que el arg incorrecto pasado al constructor correctamente plantea un error:

def testInsufficientArgs(self): foo = 0 self.assertRaises((Error), myClass = MyClass(Error, foo))

Pero me pongo ...

NameError: global name ''Error'' is not defined

¿Por qué? ¿Dónde debería estar definiendo este objeto de error? Pensé que estaba incorporado como un tipo de excepción predeterminado, ¿no?


Creo que estás pensando en Exception s. Reemplace la palabra Error en su descripción con Exception y debería estar listo para ir :-)


Qué tal esto:

class MyClass: def __init__(self, foo): if foo != 1: raise Exception("foo is not equal to 1!") import unittest class Tests(unittest.TestCase): def testSufficientArgs(self): foo = 1 MyClass(foo) def testInsufficientArgs(self): foo = 2 self.assertRaises(Exception, MyClass, foo) if __name__ == ''__main__'': unittest.main()


''Error'' en este ejemplo podría ser cualquier objeto de excepción. Creo que quizás haya leído un ejemplo de código que lo usó como marcador de posición metasintáctico para significar "La clase de excepción apropiada".

La clase base de todas las excepciones se llama ''Excepción'', y la mayoría de sus subclases son nombres descriptivos del tipo de error involucrado, como ''OSError'', ''ValueError'', ''NameError'', ''TypeError''.

En este caso, el error apropiado es ''ValueError'' (el valor de foo era incorrecto, por lo tanto, un ValueError). Recomendaría reemplazar ''Error'' con ''ValueError'' en su script.

Aquí hay una versión completa del código que está intentando escribir, estoy duplicando todo porque tiene un argumento de palabra clave raro en su ejemplo original que parece estar combinando con una tarea, y estoy usando la función ''failUnless'' nombre porque ese es el nombre sin alias de la función:

class MyClass: def __init__(self, foo): if foo != 1: raise ValueError("foo is not equal to 1!") import unittest class TestFoo(unittest.TestCase): def testInsufficientArgs(self): foo = 0 self.failUnlessRaises(ValueError, MyClass, foo) if __name__ == ''__main__'': unittest.main()

El resultado es:

. ---------------------------------------------------------------------- Ran 1 test in 0.007s OK

Hay un error en la biblioteca de pruebas de unidades ''unittest'' que corrigen otros frameworks de pruebas de unidades. Notará que es imposible obtener acceso al objeto de excepción desde el contexto de llamada. Si quiere corregir esto, tendrá que redefinir ese método en una subclase de UnitTest:

Este es un ejemplo de uso:

class TestFoo(unittest.TestCase): def failUnlessRaises(self, excClass, callableObj, *args, **kwargs): try: callableObj(*args, **kwargs) except excClass, excObj: return excObj # Actually return the exception object else: if hasattr(excClass,''__name__''): excName = excClass.__name__ else: excName = str(excClass) raise self.failureException, "%s not raised" % excName def testInsufficientArgs(self): foo = 0 excObj = self.failUnlessRaises(ValueError, MyClass, foo) self.failUnlessEqual(excObj[0], ''foo is not equal to 1!'')

Copié la función failUnlessRaises de unittest.py de python2.5 y la modifiqué ligeramente.