Python:当涉及Try-Except时,断言引发自定义异常的单元测试失败
我正在尝试编写一个单元测试,它断言嵌套的自定义异常是由函数引发的 下面的示例代码通过:Python:当涉及Try-Except时,断言引发自定义异常的单元测试失败,python,unit-testing,exception,try-catch,Python,Unit Testing,Exception,Try Catch,我正在尝试编写一个单元测试,它断言嵌套的自定义异常是由函数引发的 下面的示例代码通过: from unittest import TestCase class MyClass(): class MyException(Exception): pass def fail(): raise MyClass.MyException() class MyTests(TestCase): def test_throwsException(self):
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必须是异常类型的含义,因为我假设我的自定义异常是异常类型
为什么第二个版本的try-except失败了?问题是您已经将异常类的定义嵌套在枚举中:
class Weekdays(Enum):
MONDAY = 'mon'
TUESDAY = 'tue'
WEDNESDAY = 'wed'
THURSDAY = 'thu'
FRIDAY = 'fri'
class InvalidValue(Exception):
pass
enum(通过元类欺骗)将其类属性设置为enum类的单个实例,使用您在该enum实例的.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
同样,在解析中,您需要:
raise Weekdays.InvalidValue.value() from e
但是您最好只在模块级别定义InvalidValue
。为什么要在枚举中定义异常类?这将使您在工作日.InvalidValue
中访问的内容成为具有该类属性的.value
的枚举。。。就像在枚举中定义的任何其他类属性一样。把它从枚举中删除。嗯,我明白了!这确实解决了问题。似乎枚举类中不能有嵌套类。你能加上这个作为回答吗?这样我就可以接受了?顺便说一下,为了组织的目的,我嵌套了我的自定义异常。嗯,它们可以。但是嵌套类并不是什么特别的事情,它相当于my_attribute=SomeClass
。通常,嵌套类在Python中不是常见的模式。这真的没有什么优势。代码组织的基本单位是模块。我最近看到了一些关于python中嵌套类的问题。我认为对于嵌套类的工作方式有一个常见的误解,即它们根本不从它们所在的类继承任何东西。也许有人可以在这方面纠正我,但我能看到的嵌套类的唯一好处是组织名称空间。然后,当外部类更改属性访问的工作方式时,即使这样也可能会退出窗口。@Aaron是的,将一个类定义粘贴到另一个类定义的主体中的唯一效果是,生成的类对象位于它嵌套的类的命名空间中。当然,对于元类,各种各样的欺骗都可能发生,如上所示。我曾经使用过一两次嵌套类,我相信它们在Django中使用过(Django严重依赖元类魔法)。但它几乎总是比它的价值更麻烦。如果一个类是“private”并且不应该公开,只需将它放在模块级别并使用一个下划线,这就是Pythonic约定。
raise Weekdays.InvalidValue.value() from e