我已经在内部创建了自定义异常 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
代码中其他地方的另一个功能会引发一个不同的实例,说明DataException
数据pandas
帧中是否没有足够的数据。我想用来unittest
确保它返回适当的异常及其相应的消息。
用一个简单的例子,为什么这不起作用:
from .. import DataException
def foobar():
raise DataException('E101')
import unittest
with unittest.TestCase.assertRaises(DataException):
foobar()
如此处建议:Python assertRaises在用户定义的异常上
我收到此错误:
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
?
您正在尝试使用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
。
现在,您必须使用测试运行器来管理您的测试用例。加
if __name__ == '__main__':
unittest.main()
在底部,然后将文件作为脚本运行。然后,您的测试用例将被自动发现并执行。
从技术上讲,可以在此类环境之外使用断言,请参阅是否可以在TestCase之外使用Python单元测试断言?,但是我建议您坚持创建测试用例。
要进一步验证所引发异常的代码和消息,请使用;将输入上下文时返回的值分配给新名称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')
最后但并非最不重要的一点是,请考虑使用的子类,DataException
而不要使用单独的错误代码。这样,您的API用户就可以捕获这些子类中的一个来处理特定的错误代码,而不必对代码进行额外的测试,并在不应该处理特定代码的情况下重新引发。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句