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

And*_*usa 154 python unit-testing

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

def setUp(self):

  self.testListNone = None

def testListSlicing(self):

  self.assertRaises(TypeError, self.testListNone[:1])
Run Code Online (Sandbox Code Playgroud)

我期待测试通过,但我得到例外:

Traceback (most recent call last):

    self.assertRaises(TypeError, self.testListNone[:1])

TypeError: 'NoneType' object is unsubscriptable
Run Code Online (Sandbox Code Playgroud)

我认为assertRaises会通过,因为会引发TypeError异常?

mou*_*uad 235

如果您使用的是python2.7或更高版本,则可以使用assertRaises作为上下文管理器的功能,并执行以下操作:

with self.assertRaises(TypeError):
    self.testListNone[:1]
Run Code Online (Sandbox Code Playgroud)

如果你使用python2.6,那么除了现在使用的另一种方法是使用unittest2,这是python2.6的unittest新功能的后端,你可以使用上面的代码使它工作.

注意:我是unittest的新功能(SkipTest,测试发现......)的忠实粉丝所以我打算尽可能多地使用unittest2.我建议做同样的事情,因为在python2.6中有比单元测试更多的东西.

  • 2.7 _或以上_ .. 你在向我们隐藏 Python 2.8 吗? (2认同)

Bas*_*ink 126

问题是TypeError被提出"之前" assertRaises被调用,因为该参数assertRaises需要进行评估,可以调用该方法之前.你需要传递一个lambda表达式:

self.assertRaises(TypeError, lambda: self.testListNone[:1])
Run Code Online (Sandbox Code Playgroud)

  • 可能是最好的答案 (3认同)

unu*_*tbu 80

通常的使用方法assertRaises是调用函数:

self.assertRaises(TypeError, test_function, args)
Run Code Online (Sandbox Code Playgroud)

测试函数调用test_function(args)引发TypeError.

问题self.testListNone[:1]是Python在assertRaises调用方法之前立即评估表达式.将test_functionargs作为单独的参数传递的全部原因self.assertRaises是允许从块内assertRaises调用,允许捕获异常.test_function(args)try...exceptassertRaises

既然你已经定义了self.testListNone = None,并且你需要一个函数来调用,你可以像这样使用operator.itemgetter:

import operator
self.assertRaises(TypeError, operator.itemgetter, (self.testListNone,slice(None,1)))
Run Code Online (Sandbox Code Playgroud)

以来

operator.itemgetter(self.testListNone,slice(None,1))
Run Code Online (Sandbox Code Playgroud)

是一种冗长的说法self.testListNone[:1],但它将函数(operator.itemgetter)与参数分开.

  • 这绝对是正确的答案,可以解释问题。 (3认同)
  • 对于单个assertRaises,这看起来是最好的答案.对于大量基于异常的测试(假设它们都具有相同的异常类型),使用self.assertRaises(...)将是一个不错的选择. (2认同)
  • 是的,这应该是正确的答案,因为它实际上解释了问题。 (2认同)

saa*_*aaj 7

完整的代码段如下所示。它扩展了@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))
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你!这种彻底性正是我所寻求的:-) (2认同)