如何正确使用unit testing的assertRaises()与NoneType对象?
我做了一个简单的testing用例:
def setUp(self): self.testListNone = None def testListSlicing(self): self.assertRaises(TypeError, self.testListNone[:1])
我期待testing通过,但我得到例外:
Traceback (most recent call last): self.assertRaises(TypeError, self.testListNone[:1]) TypeError: 'NoneType' object is unsubscriptable
我认为assertRaises会通过TypeErrorexception将被提出?
如果您使用python2.7或更高版本,则可以使用assertRaises作为上下文pipe理器的function,并执行以下操作:
with self.assertRaises(TypeError): self.testListNone[:1]
如果你正在使用python2.6之外的其他方法,直到现在使用unittest2这是unit testing新function的后端口到python2.6,你可以使用上面的代码使其工作。
注意:我是unit testing新function(SkipTest,testing发现…)的忠实粉丝,所以我打算尽可能多地使用unittest2。 我build议做同样的事情,因为python2.6中有很多unit testing。
问题是TypeError
在assertRaises
被调用之前被' assertRaises
',因为assertRaises
的参数在assertRaises
该方法之前需要被评估。 你需要传递一个lambda
expression式,如:
self.assertRaises(TypeError, lambda: self.testListNone[:1])
通常使用assertRaises
是调用一个函数:
self.assertRaises(TypeError, test_function, args)
testing函数调用test_function(args)引发TypeError。
self.testListNone[:1]
是Python在调用assertRaises
方法之前立即计算expression式。 test_function
和args
作为独立parameter passing给self.assertRaises
的全部原因是允许assertRaises
从try...except
块中调用test_function(args)
,从而允许assertRaises
捕获exception。
既然你已经定义了self.testListNone = None
,并且你需要一个函数来调用,你可以使用operator.itemgetter,像这样:
import operator self.assertRaises(TypeError, operator.itemgetter, (self.testListNone,slice(None,1)))
以来
operator.itemgetter(self.testListNone,slice(None,1))
是一个冗长的说法self.testListNone[:1]
,但它分开函数( operator.itemgetter
)从参数。
完整的代码片段如下所示。 它扩展了@ mouad的错误消息的断言(或通常str
的args
表示),这可能是有用的。
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))