如何正确使用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该方法之前需要被评估。 你需要传递一个lambdaexpression式,如:
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))