单元测试中的自定义异常

2024-09-29 21:56:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经在errors.py中创建了自定义异常

mapper = {
    'E101':
    'There is no data at all for these constraints',
    'E102':
    'There is no data for these constraints in this market, try changing market',
    'E103':
    'There is no data for these constraints during these dates, try changing dates',
}


class DataException(Exception):
    def __init__(self, code):
        super().__init__()
        self.msg = mapper[code]

    def __str__(self):
        return self.msg

如果pandas数据帧中没有足够的数据,则代码中其他地方的另一个函数会引发DataException的不同实例。我想使用unittest来确保它返回相应的异常及其相应的消息。在

举一个简单的例子,为什么这不起作用:

^{pr2}$

正如这里建议的:Python assertRaises on user-defined exceptions

我得到这个错误:

TypeError: assertRaises() missing 1 required positional argument: 'expected_exception'

或者选择:

def foobar():
    raise DataException('E101')

import unittest
unittest.TestCase.assertRaises(DataException, foobar)

结果:

TypeError: assertRaises() arg 1 must be an exception type or tuple of exception types

为什么它不将DataException识别为Exception?为什么链接的stackoverflow问题答案在没有为assertRaises提供第二个参数的情况下工作?在


Tags: noselffordataisdefexceptionunittest
1条回答
网友
1楼 · 发布于 2024-09-29 21:56:57

您正试图在不创建实例的情况下使用TestCase类的方法;这些方法不是设计成以这种方式使用的。在

unittest.TestCase.assertRaises是一个非绑定方法。您可以在您定义的TestCase类的测试方法中使用它:

class DemoTestCase(unittest.TestCase):
    def test_foobar(self):
        with self.assertRaises(DataException):
            foobar()

由于未绑定方法未获得传入的self,因此引发了此错误。因为unittest.TestCase.assertRaises同时需要self和第二个名为expected_exception的参数,所以当DataException作为self的值传入时,会出现异常。在

现在确实需要使用测试运行器来管理测试用例;添加

^{pr2}$

以脚本的形式运行文件。然后自动发现并执行测试用例。在

从技术上讲,在这样的环境之外使用断言是可能的,请参见Is there a way to use Python unit test assertions outside of a TestCase?,但我建议您坚持创建测试用例。在

要进一步验证有关引发异常的代码和消息,请使用with ... as <target>:将输入上下文时返回的值分配给新名称;上下文管理器对象捕获引发的异常,以便您可以对其进行断言:

with self.assertRaises(DataException) as context:
    foobar()

self.assertEqual(context.exception.code, 'E101')
self.assertEqual(
    context.exception.msg,
    'There is no data at all for these constraints')

参见^{} documentation。在

最后但并非最不重要的是,考虑使用DataException子类,而不是使用单独的错误代码。这样,API用户只需捕获其中的一个子类来处理特定的错误代码,而不必对代码进行额外的测试,并在不应该处理特定代码的情况下重新引发。在

相关问题 更多 >

    热门问题