J'ai fait un cas de test simple:
def setUp(self):
self.testListNone = None
def testListSlicing(self):
self.assertRaises(TypeError, self.testListNone[:1])
et je m'attends à ce que le test passe, mais j'obtiens une exception:
Traceback (most recent call last):
self.assertRaises(TypeError, self.testListNone[:1])
TypeError: 'NoneType' object is unsubscriptable
Je pensais que assertRaises passera puisque l'exception TypeError sera levée?
Si vous utilisez python2.7 ou supérieur, vous pouvez utiliser la capacité de assertRaises à utiliser en tant que gestionnaire de contexte et faire:
with self.assertRaises(TypeError):
self.testListNone[:1]
Si vous utilisez python2.6, vous pouvez utiliser nittest2 , qui est un port arrière de la nouvelle fonctionnalité unittest de python2.6, et vous pouvez le faire fonctionner avec le code ci-dessus. .
N.B: Je suis un grand fan de la nouvelle fonctionnalité (SkipTest, test discovery ...) de unittest alors je compte utiliser unittest2 autant que je peux. Je conseille de faire la même chose car il y a beaucoup plus que ce qui est unittest livré avec python2.6 <.
Le problème est que TypeError
est soulevé 'avant' assertRaises
soit appelé car les arguments de assertRaises
doivent être évalués avant que la méthode puisse être appelée. Vous devez passer une expression lambda
comme:
self.assertRaises(TypeError, lambda: self.testListNone[:1])
La manière habituelle d’utiliser assertRaises
consiste à appeler une fonction:
self.assertRaises(TypeError, test_function, args)
pour tester que l'appel de fonction test_function (args) déclenche une erreur TypeError.
Le problème avec self.testListNone[:1]
Est que Python évalue l'expression immédiatement, avant que la méthode assertRaises
ne soit appelée. La raison principale pour laquelle test_function
Et args
est passé sous forme d'arguments distincts à self.assertRaises
, ce qui permet à assertRaises
d'appeler test_function(args)
à partir d'un bloc try...except
, permettant ainsi à assertRaises
pour attraper l'exception.
Puisque vous avez défini self.testListNone = None
Et que vous avez besoin d’une fonction à appeler, vous pouvez utiliser operator.itemgetter comme ceci:
import operator
self.assertRaises(TypeError, operator.itemgetter, (self.testListNone,slice(None,1)))
puisque
operator.itemgetter(self.testListNone,slice(None,1))
est une manière longue de dire self.testListNone[:1]
, mais qui sépare la fonction (operator.itemgetter
) des arguments.
Un extrait complet ressemblerait à ce qui suit. Il étend la réponse de @ mouad à l'affirmation du message d'erreur (ou généralement str
représentation de son args
), ce qui peut être utile.
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))