Ich habe einen einfachen Testfall gemacht:
def setUp(self):
self.testListNone = None
def testListSlicing(self):
self.assertRaises(TypeError, self.testListNone[:1])
und ich erwarte, dass der Test bestanden wird, aber ich bekomme eine Ausnahme:
Traceback (most recent call last):
self.assertRaises(TypeError, self.testListNone[:1])
TypeError: 'NoneType' object is unsubscriptable
Ich dachte, dass assertRaises vergehen wird, da die TypeError-Ausnahme ausgelöst wird?
Wenn Sie Python2.7 oder höher verwenden, können Sie die Funktion assertRaises als Kontext-Manager verwenden und Folgendes tun:
with self.assertRaises(TypeError):
self.testListNone[:1]
Wenn Sie Python2.6 verwenden, können Sie auch nittest2 verwenden. Dies ist ein Backport der unittest-Funktion von Python2.6, und Sie können es mit dem obigen Code zum Laufen bringen .
NB: Ich bin ein großer Fan der neuen Funktion (SkipTest, test discovery ...) von unittest, daher beabsichtige ich, unittest2 so oft wie möglich zu verwenden. Ich rate, dasselbe zu tun, da es in python2.6 <viel mehr gibt als das, was unittest mit sich bringt.
Das Problem ist, dass TypeError
'ausgelöst wird, bevor' assertRaises
aufgerufen wird, da die Argumente für assertRaises
ausgewertet werden müssen, bevor die Methode aufgerufen werden kann. Sie müssen einen lambda
Ausdruck wie folgt übergeben:
self.assertRaises(TypeError, lambda: self.testListNone[:1])
Die übliche Methode, assertRaises
zu verwenden, besteht darin, eine Funktion aufzurufen:
self.assertRaises(TypeError, test_function, args)
um zu testen, dass der Funktionsaufruf test_function (args) einen TypeError auslöst.
Das Problem mit self.testListNone[:1]
Ist, dass Python) den Ausdruck unmittelbar vor dem Aufruf der assertRaises
-Methode auswertet. Der ganze Grund, warum test_function
Und args
wird als separates Argument an self.assertRaises
übergeben, damit assertRaises
test_function(args)
aus einem try...except
- Block aufrufen und assertRaises
, um die Ausnahme abzufangen.
Da Sie self.testListNone = None
Definiert haben und eine Funktion zum Aufrufen benötigen, können Sie operator.itemgetter wie folgt verwenden:
import operator
self.assertRaises(TypeError, operator.itemgetter, (self.testListNone,slice(None,1)))
schon seit
operator.itemgetter(self.testListNone,slice(None,1))
ist eine langatmige Art, self.testListNone[:1]
zu sagen, die jedoch die Funktion (operator.itemgetter
) von den Argumenten trennt.
Das vollständige Snippet würde folgendermaßen aussehen. Es erweitert die Antwort von @ mouad auf die Behauptung der Fehlermeldung (oder allgemein die str
Repräsentation der args
), was nützlich sein kann.
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))