unittest example español assertraises python unit-testing

python - example - ¿Cómo usar adecuadamente assertRaises() de testing de unidades con objetos NoneType?



assertraises python example (4)

El fragmento completo sería similar al siguiente. Extiende la respuesta de @mouad a la afirmación en el mensaje de error (o en general representación str de sus args ), que puede ser útil.

from unittest import TestCase class TestNoneTypeError(TestCase): def setUp(self): self.testListNone = None def testListSlicing(self): with self.assertRaises(TypeError) as ctx: self.testListNone[:1] self.assertEqual("''NoneType'' object is not subscriptable", str(ctx.exception))

Esta pregunta ya tiene una respuesta aquí:

Hice un caso de prueba simple:

def setUp(self): self.testListNone = None def testListSlicing(self): self.assertRaises(TypeError, self.testListNone[:1])

y estoy esperando que pase la prueba, pero estoy recibiendo una excepción:

Traceback (most recent call last): self.assertRaises(TypeError, self.testListNone[:1]) TypeError: ''NoneType'' object is unsubscriptable

Pensé que assertRaises pasará ya que se generará la excepción TypeError.


El problema es que TypeError se levanta ''antes'' de que se llame a assertRaises ya que los argumentos para assertRaises necesitan ser evaluados antes de que se pueda llamar al método. Debes pasar una expresión lambda como:

self.assertRaises(TypeError, lambda: self.testListNone[:1])


La forma habitual de usar assertRaises es llamar a una función:

self.assertRaises(TypeError, test_function, args)

para probar que la función llamada test_function (args) genera un TypeError.

El problema con self.testListNone[:1] es que Python evalúa la expresión inmediatamente antes de assertRaises método assertRaises . La razón por la cual test_function y args se pasan como argumentos separados a self.assertRaises es permitir que assertRaises llame a test_function(args) desde dentro de un bloque try...except , permitiendo a assertRaises capturar la excepción.

Como ha definido self.testListNone = None y necesita una función para llamar, puede usar operator.itemgetter siguiente manera:

import operator self.assertRaises(TypeError, operator.itemgetter, (self.testListNone,slice(None,1)))

ya que

operator.itemgetter(self.testListNone,slice(None,1))

es una forma self.testListNone[:1] de decir self.testListNone[:1] , pero que separa la función ( operator.itemgetter ) de los argumentos.


Si está utilizando python2.7 o superior, puede usar la capacidad de assertRaises para usarlo como administrador de contexto y hacer:

with self.assertRaises(TypeError): self.testListNone[:1]

Si está usando python2.6 de otra manera además del que se le ha dado hasta ahora, use unittest2 que es un puerto trasero de la nueva característica unittest para python2.6, y puede hacer que funcione usando el código anterior.

NB: Soy un gran admirador de la nueva característica (SkipTest, prueba de descubrimiento ...) de unittest así que tengo la intención de usar unittest2 tanto como pueda. Aconsejo hacer lo mismo porque hay mucho más de lo que viene con unittest en python2.6 <.