python - Python:当涉及 Try-Except 时,断言自定义异常被引发的单元测试失败
问题描述
我正在尝试编写一个单元测试,断言我的嵌套自定义异常是由函数引发的。
下面的示例代码通过:
from unittest import TestCase
class MyClass():
class MyException(Exception):
pass
def fail():
raise MyClass.MyException()
class MyTests(TestCase):
def test_throwsException(self):
with self.assertRaises(MyClass.MyException):
fail()
但是,当我的提升代码涉及 try-except 时,我的测试失败:
from unittest import TestCase
from enum import Enum
class Weekdays(Enum):
MONDAY = 'mon'
TUESDAY = 'tue'
WEDNESDAY = 'wed'
THURSDAY = 'thu'
FRIDAY = 'fri'
class InvalidValue(Exception):
pass
def parse(key: str) -> Weekdays:
try:
return Weekdays(key)
except Exception as e:
raise Weekdays.InvalidValue() from e
class MyTests(TestCase):
def test_throwsException(self):
with self.assertRaises(Weekdays.InvalidValue):
parse('invalid')
它返回以下错误:
E
======================================================================
ERROR: test_throwsException (test_main.MyTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "E:\PythonCodes\playground\test_main.py", line 25, in test_throwsException
with self.assertRaises(Weekdays.InvalidValue):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38\lib\unittest\case.py", line 816, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38\lib\unittest\case.py", line 187, in handle
raise TypeError('%s() arg 1 must be %s' %
TypeError: assertRaises() arg 1 must be an exception type or tuple of exception types
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
我不太明白什么arg 1 must be an exception type
意思,因为我假设我的自定义异常是异常类型。
为什么带有 try-except 的第二个版本失败了?
解决方案
问题是您已将异常类的定义嵌套在枚举中:
class Weekdays(Enum):
MONDAY = 'mon'
TUESDAY = 'tue'
WEDNESDAY = 'wed'
THURSDAY = 'thu'
FRIDAY = 'fri'
class InvalidValue(Exception):
pass
枚举(通过元类诡计)使它们的类属性成为枚举类的单例实例.value
,并使用您在该枚举实例内部的定义中分配给属性的值。就像您在枚举中定义的其他类属性一样。所以,考虑:
In [1]: from enum import Enum
In [2]:
...: class Weekdays(Enum):
...: MONDAY = 'mon'
...: TUESDAY = 'tue'
...: WEDNESDAY = 'wed'
...: THURSDAY = 'thu'
...: FRIDAY = 'fri'
...:
...: class InvalidValue(Exception):
...: pass
...:
In [3]: Weekdays.MONDAY
Out[3]: <Weekdays.MONDAY: 'mon'>
In [4]: Weekdays.MONDAY.value
Out[4]: 'mon'
In [5]: Weekdays.InvalidValue
Out[5]: <Weekdays.InvalidValue: <class '__main__.Weekdays.InvalidValue'>>
In [6]: Weekdays.InvalidValue.value
Out[6]: __main__.Weekdays.InvalidValue
所以,你可以使用:
with self.assertRaises(Weekdays.InvalidValue.value):
...
同样,在 中parse
,您需要:
raise Weekdays.InvalidValue.value() from e
但是你最好只InvalidValue
在模块级别定义。
推荐阅读
- sql - SQL - 从没有 UNION 的条件连接中选择一个值
- json - Golang 可变字段
- python - 如何获取下一个标签的文本?(美汤)
- django - Django过滤器使用Q和具有不同值的多个字段
- python - conda 环境中的依赖关系 plot-vcfstats
- c++ - 显示所有 c++ #include 依赖项
- excel - 如何从vba例程执行单元格(行,列)中的公式
- r - R中的文本编码与日文字符
- ansible - Jinja2 循环中未定义的变量 - 尝试访问索引
- javascript - 循环 URL 并提取值并存储在 JSON JavaScript 中