【问题标题】:How to properly use unit-testing's assertRaises() with NoneType objects? [duplicate]如何正确使用单元测试的 assertRaises() 和 NoneType 对象? [复制]
【发布时间】:2011-08-31 12:31:55
【问题描述】:

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

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 异常会 被抚养?

【问题讨论】:

标签: python unit-testing


【解决方案1】:

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

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

如果您正在使用python2.6,除了到目前为止给定的方法之外的另一种方法是使用unittest2,它是python2.6的unittest新功能的后端口,您可以使用上面的代码使其工作。

N.B:我非常喜欢 unittest 的新功能(SkipTest、测试发现...),所以我打算尽可能多地使用 unittest2。我建议也这样做,因为在 python2.6 中,unittest 的功能远不止这些 <.>

【讨论】:

  • 2.7 或更高版本 .. 你是在向我们隐藏 Python 2.8 吗?
  • 您提到的代码似乎无法解决在断言比较之前结束脚本的问题。仍然没有通过测试(使用 python 3.10)
【解决方案2】:

问题是 TypeError 在调用 assertRaises 之前被提升,因为在调用方法之前需要评估 assertRaises 的参数。您需要传递一个lambda 表达式,例如:

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

【讨论】:

【解决方案3】:

assertRaises的常用用法是调用函数:

self.assertRaises(TypeError, test_function, args)

测试函数调用 test_function(args) 是否引发 TypeError。

self.testListNone[:1] 的问题在于 Python 在调用 assertRaises 方法之前立即计算表达式。将test_functionargs 作为单独的参数传递给self.assertRaises 的全部原因是允许assertRaisestry...except 块内调用test_function(args),从而允许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) 与参数分开。

【讨论】:

  • 对于单个 assertRaises,这看起来是最好的答案。对于大量基于异常的测试(假设它们都具有相同的异常类型) with self.assertRaises(...) 将是一个不错的选择。
  • 是的,这应该是正确的答案,因为它实际上解释了问题。
  • 这绝对是正确的答案,它解释了问题。
  • 你能帮我解决一个相关的问题吗? stackoverflow.com/questions/39909935/…
  • +1 可以简化为self.assertRaises(TypeError, self.testListNone.__getitem__, slice(None,1)),因为operator.itemgetter增加了一些小的无用复杂度。
【解决方案4】:

完整的 sn-p 如下所示。它将@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))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 2021-07-04
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多