如何正确使用单元测试的assertRaises()与NoneType对象?

时间:2011-05-23 22:38:25

标签: python unit-testing

我做了一个简单的测试用例:

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异常而通过 被提升?

4 个答案:

答案 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_functionargs作为单独参数传递给self.assertRaises的全部原因是允许assertRaisestest_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))