我做了一个简单的测试用例:
def setUp(self):
self.testListNone = None
def testListSlicing(self):
self.assertRaises(TypeError, self.testListNone[:1])
我期待测试通过,但我得到例外:
Traceback (most recent call last):
self.assertRaises(TypeError, self.testListNone[:1])
TypeError: 'NoneType' object is unsubscriptable
我认为assertRaises会因为TypeError异常而通过 被提升?
答案 0 :(得分:221)
如果您使用的是python2.7或更高版本,则可以使用assertRaises的功能作为上下文管理器并执行:
with self.assertRaises(TypeError):
self.testListNone[:1]
如果你使用python2.6,那么除了现在使用的另一种方法是使用unittest2这是python2.6的unittest新功能的后端口,你可以使用上面的代码使它工作
N.B:我是unittest新功能(SkipTest,测试发现......)的忠实粉丝所以我打算尽可能多地使用unittest2。我建议做同样的事情因为在python2.6<。
中有比单元测试更多的东西。答案 1 :(得分:118)
问题是在调用'TypeError
之前assertRaises
被提升',因为在调用方法之前需要评估assertRaises
的参数。您需要传递lambda
表达式,如:
self.assertRaises(TypeError, lambda: self.testListNone[:1])
答案 2 :(得分:77)
使用assertRaises
的常用方法是调用函数:
self.assertRaises(TypeError, test_function, args)
测试函数调用test_function(args)引发TypeError。
self.testListNone[:1]
的问题是Python在调用assertRaises
方法之前立即评估表达式。将test_function
和args
作为单独参数传递给self.assertRaises
的全部原因是允许assertRaises
在test_function(args)
块内调用try...except
,允许assertRaises
捕获异常。
由于您已定义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
)与参数分开。
答案 3 :(得分:4)
完整代码段如下所示。它扩展了@ 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))